using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; namespace AForge.Imaging; public class ExhaustiveBlockMatching : IBlockMatching { private class MatchingsSorter : IComparer { public int Compare(BlockMatch x, BlockMatch y) { float num = y.Similarity - x.Similarity; if (!(num > 0f)) { if (!(num < 0f)) { return 0; } return -1; } return 1; } } private int blockSize = 16; private int searchRadius = 12; private float similarityThreshold = 0.9f; public int SearchRadius { get { return searchRadius; } set { searchRadius = value; } } public int BlockSize { get { return blockSize; } set { blockSize = value; } } public float SimilarityThreshold { get { return similarityThreshold; } set { similarityThreshold = System.Math.Min(1f, System.Math.Max(0f, value)); } } public ExhaustiveBlockMatching() { } public ExhaustiveBlockMatching(int blockSize, int searchRadius) { this.blockSize = blockSize; this.searchRadius = searchRadius; } public List ProcessImage(Bitmap sourceImage, List coordinates, Bitmap searchImage) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) BitmapData val = sourceImage.LockBits(new Rectangle(0, 0, ((Image)sourceImage).Width, ((Image)sourceImage).Height), (ImageLockMode)1, ((Image)sourceImage).PixelFormat); BitmapData val2 = searchImage.LockBits(new Rectangle(0, 0, ((Image)searchImage).Width, ((Image)searchImage).Height), (ImageLockMode)1, ((Image)searchImage).PixelFormat); try { return ProcessImage(new UnmanagedImage(val), coordinates, new UnmanagedImage(val2)); } finally { sourceImage.UnlockBits(val); searchImage.UnlockBits(val2); } } public List ProcessImage(BitmapData sourceImageData, List coordinates, BitmapData searchImageData) { return ProcessImage(new UnmanagedImage(sourceImageData), coordinates, new UnmanagedImage(searchImageData)); } public unsafe List ProcessImage(UnmanagedImage sourceImage, List coordinates, UnmanagedImage searchImage) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Invalid comparison between Unknown and I4 if (sourceImage.Width != searchImage.Width || sourceImage.Height != searchImage.Height) { throw new InvalidImagePropertiesException("Source and search images sizes must match"); } if ((int)sourceImage.PixelFormat != 198659 && (int)sourceImage.PixelFormat != 137224) { throw new UnsupportedImageFormatException("Source images can be graysclae (8 bpp indexed) or color (24 bpp) image only"); } if (sourceImage.PixelFormat != searchImage.PixelFormat) { throw new InvalidImagePropertiesException("Source and search images must have same pixel format"); } int count = coordinates.Count; List list = new List(); int width = sourceImage.Width; int height = sourceImage.Height; int stride = sourceImage.Stride; int num = (((int)sourceImage.PixelFormat == 198659) ? 1 : 3); int num2 = blockSize / 2; int num3 = 2 * searchRadius; int num4 = blockSize * num; int num5 = stride - blockSize * num; int num6 = blockSize * blockSize * num * 255; int num7 = (int)(similarityThreshold * (float)num6); byte* ptr = (byte*)sourceImage.ImageData.ToPointer(); byte* ptr2 = (byte*)searchImage.ImageData.ToPointer(); for (int i = 0; i < count; i++) { int x = coordinates[i].X; int y = coordinates[i].Y; if (x - num2 < 0 || x + num2 >= width || y - num2 < 0 || y + num2 >= height) { continue; } int num8 = x - num2 - searchRadius; int num9 = y - num2 - searchRadius; int x2 = x; int y2 = y; int num10 = int.MaxValue; for (int j = 0; j < num3; j++) { if (num9 + j < 0 || num9 + j + blockSize >= height) { continue; } for (int k = 0; k < num3; k++) { int num11 = num8 + k; int num12 = num9 + j; if (num11 < 0 || num12 + blockSize >= width) { continue; } byte* ptr3 = ptr + (nint)(y - num2) * (nint)stride + (nint)(x - num2) * (nint)num; byte* ptr4 = ptr2 + (nint)num12 * (nint)stride + (nint)num11 * (nint)num; int num13 = 0; for (int l = 0; l < blockSize; l++) { int num14 = 0; while (num14 < num4) { int num15 = *ptr3 - *ptr4; num13 = ((num15 <= 0) ? (num13 - num15) : (num13 + num15)); num14++; ptr3++; ptr4++; } ptr3 += num5; ptr4 += num5; } if (num13 < num10) { num10 = num13; x2 = num11 + num2; y2 = num12 + num2; } } } int num16 = num6 - num10; if (num16 >= num7) { list.Add(new BlockMatch(new IntPoint(x, y), new IntPoint(x2, y2), (float)num16 / (float)num6)); } } list.Sort(new MatchingsSorter()); return list; } }