aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.RemoteDesktop/Comparers/RasterBitmapComparer.cs
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-03-02 23:30:34 +0200
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-03-02 23:30:34 +0200
commit0dcd742a3c35527386a93e1b1ef761c2aeff8308 (patch)
treed5adb3fee35e73af95fa5d68b5316d25522471de /Software/Visual_Studio/Tango.RemoteDesktop/Comparers/RasterBitmapComparer.cs
parent1a7fb274158f8a0e279aef26206a65fefac8c4c3 (diff)
downloadTango-0dcd742a3c35527386a93e1b1ef761c2aeff8308.tar.gz
Tango-0dcd742a3c35527386a93e1b1ef761c2aeff8308.zip
Implemented Tango.RemoteDesktop.
Implemented png 8 bit quantization. Implemented RasterFrame bounds clipping. Refactored VectorFrame to use indexed colors.
Diffstat (limited to 'Software/Visual_Studio/Tango.RemoteDesktop/Comparers/RasterBitmapComparer.cs')
-rw-r--r--Software/Visual_Studio/Tango.RemoteDesktop/Comparers/RasterBitmapComparer.cs120
1 files changed, 120 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Tango.RemoteDesktop/Comparers/RasterBitmapComparer.cs b/Software/Visual_Studio/Tango.RemoteDesktop/Comparers/RasterBitmapComparer.cs
new file mode 100644
index 000000000..34250cc59
--- /dev/null
+++ b/Software/Visual_Studio/Tango.RemoteDesktop/Comparers/RasterBitmapComparer.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.RemoteDesktop.Frames;
+
+namespace Tango.RemoteDesktop.Comparers
+{
+ /// <summary>
+ /// Represents a raster <see cref="IBitmapComparer{TFrame}"/> comparer which will compare and return a <see cref="RasterFrame"/> difference.
+ /// </summary>
+ /// <seealso cref="Tango.RemoteDesktop.IBitmapComparer{Tango.RemoteDesktop.Frames.RasterFrame}" />
+ public class RasterBitmapComparer : IBitmapComparer<RasterFrame>
+ {
+ /// <summary>
+ /// Creates the difference as <see cref="RasterFrame"/>.
+ /// </summary>
+ /// <param name="previousBitmap">The previous bitmap.</param>
+ /// <param name="currentBitmap">The current bitmap.</param>
+ /// <returns></returns>
+ /// <exception cref="InvalidOperationException">
+ /// Cannot compare image. They are the same instance
+ /// or
+ /// Cannot compare image of different size.
+ /// </exception>
+ unsafe public BitmapComparerResult<RasterFrame> CreateDifference(Bitmap previousBitmap, Bitmap currentBitmap)
+ {
+ if (previousBitmap == null | currentBitmap == null)
+ throw new InvalidOperationException("Cannot compare image. They are the same instance");
+
+ if (previousBitmap.Height != currentBitmap.Height || previousBitmap.Width != currentBitmap.Width)
+ throw new InvalidOperationException("Cannot compare image of different size.");
+
+ bool hasDifference = false;
+
+ Color matchColor = Color.Transparent;
+
+ Bitmap diffImage = currentBitmap.Clone() as Bitmap;
+
+ int height = previousBitmap.Height;
+ int width = previousBitmap.Width;
+
+ BitmapData data1 = previousBitmap.LockBits(new Rectangle(0, 0, width, height),
+ ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
+ BitmapData data2 = currentBitmap.LockBits(new Rectangle(0, 0, width, height),
+ ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
+ BitmapData diffData = diffImage.LockBits(new Rectangle(0, 0, width, height),
+ ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
+
+ byte* data1Ptr = (byte*)data1.Scan0;
+ byte* data2Ptr = (byte*)data2.Scan0;
+ byte* diffPtr = (byte*)diffData.Scan0;
+
+ byte[] swapColor = new byte[4];
+ swapColor[0] = matchColor.B;
+ swapColor[1] = matchColor.G;
+ swapColor[2] = matchColor.R;
+ swapColor[3] = matchColor.A;
+
+ int rowPadding = data1.Stride - (previousBitmap.Width * 4);
+
+ // iterate over height (rows)
+ for (int i = 0; i < height; i++)
+ {
+ // iterate over width (columns)
+ for (int j = 0; j < width; j++)
+ {
+ int same = 0;
+
+ byte[] tmp = new byte[4];
+
+ // compare pixels and copy new values into temporary array
+ for (int x = 0; x < 4; x++)
+ {
+ tmp[x] = data2Ptr[0];
+ if (data1Ptr[0] == data2Ptr[0])
+ {
+ same++;
+ }
+ data1Ptr++; // advance image1 ptr
+ data2Ptr++; // advance image2 ptr
+ }
+
+ // swap color or add new values
+ for (int x = 0; x < 4; x++)
+ {
+ diffPtr[0] = (same == 4) ? swapColor[x] : tmp[x];
+ diffPtr++; // advance diff image ptr
+ }
+
+ if (same != 4)
+ {
+ hasDifference = true;
+ }
+ }
+
+ // at the end of each column, skip extra padding
+ if (rowPadding > 0)
+ {
+ data1Ptr += rowPadding;
+ data2Ptr += rowPadding;
+ diffPtr += rowPadding;
+ }
+ }
+
+ previousBitmap.UnlockBits(data1);
+ currentBitmap.UnlockBits(data2);
+ diffImage.UnlockBits(diffData);
+
+ return new BitmapComparerResult<RasterFrame>()
+ {
+ Frame = new RasterFrame(diffImage),
+ ContainsDifference = hasDifference
+ };
+ }
+ }
+}