static bool SearchBytes(BitData.RGB[] haystack, BitData.RGB[] needle, out int ix) { int len = needle.Length; int limit = haystack.Length - len; for (int i = 0; i <= limit; i++) { BitData.RGB a = haystack[i]; if (a.IsEqual(needle[0])) { BitData.RGB b = haystack[i + 1]; if (b.R == needle[1].R) { ix = i; return(true); } } } ix = -1; return(false); }
byte[] SearchFor(Bitmap capture, ushort step, ref string extra, ref ushort max, ref uint length, ref ushort width, ref ushort height) { if (capture == null) { return(null); } // BLACK&WHITE if (ImageMode == EImageMode.BlackAndWhite) { /* using (Graphics gr = Graphics.FromImage(capture)) * { * float[][] gray_matrix = new float[][] * { * new float[] { 0.299f, 0.299f, 0.299f, 0, 0 }, * new float[] { 0.587f, 0.587f, 0.587f, 0, 0 }, * new float[] { 0.114f, 0.114f, 0.114f, 0, 0 }, * new float[] { 0, 0, 0, 1, 0 }, * new float[] { 0, 0, 0, 0, 1 } * }; * * ImageAttributes ia = new ImageAttributes(); * ia.SetColorMatrix(new ColorMatrix(gray_matrix)); * ia.SetThreshold(0.8F); // Change this threshold as needed * Rectangle rc = new Rectangle(0, 0, capture.Width, capture.Height); * gr.DrawImage(capture, rc, 0, 0, capture.Width, capture.Height, GraphicsUnit.Pixel, ia); * }*/ } // BYTE ARRAY BitData array = new BitData((ushort)capture.Width, (ushort)capture.Height, ImageMode); array.ExtraBN = extra; using (MemoryStream ms = new MemoryStream()) { unsafe { BitmapData bitmapData = capture.LockBits(new Rectangle(0, 0, capture.Width, capture.Height), ImageLockMode.ReadWrite, capture.PixelFormat); int bytesPerPixel = Image.GetPixelFormatSize(capture.PixelFormat) / 8; int heightInPixels = bitmapData.Height; int widthInBytes = bitmapData.Width * bytesPerPixel; byte *ptrFirstPixel = (byte *)bitmapData.Scan0; for (int y = 0; y < heightInPixels; y++) { byte *currentLine = ptrFirstPixel + (y * bitmapData.Stride); for (int x = 0; x < widthInBytes; x = x + bytesPerPixel) { int oldBlue = currentLine[x]; int oldGreen = currentLine[x + 1]; int oldRed = currentLine[x + 2]; switch (ImageMode) { case EImageMode.BlackAndWhite: array.DataBN[y][x / bytesPerPixel] = array.ParseBN(oldRed, oldGreen, oldBlue); break; case EImageMode.RGB: array.DataRGB[y][x / bytesPerPixel] = array.ParseRGB(oldRed, oldGreen, oldBlue); break; } } } capture.UnlockBits(bitmapData); } // SEARCH HEADER byte[] HEADER = new byte[] { 0xB1, 0xA5, // MAGIC NUMBER 0x00, 0x00 // STEP }; // FIRST FRAME // {HEADER+STEP}+MAX+WIDTH+HEIGHT+SIZE => 14*8 = 112 // NEXT // {HEADER+STEP} => 4*8 = 32 // 10110001101001010000000000000000 byte[] bnHeader = BitConverter.GetBytes(step); Array.Copy(bnHeader, 0, HEADER, 2, bnHeader.Length); BitData.RGB[] rgbHeader = null; switch (ImageMode) { case EImageMode.BlackAndWhite: { string sheader = ""; foreach (byte b in HEADER) { sheader += Convert.ToString(b, 2).PadLeft(8, '0'); } bnHeader = new byte[sheader.Length]; for (int x = 0; x < bnHeader.Length; x++) { bnHeader[x] = sheader[x] == '1' ? (byte)1 : (byte)0; } break; } case EImageMode.RGB: { rgbHeader = new BitData.RGB[] { new BitData.RGB(HEADER[0], HEADER[1], HEADER[2]), new BitData.RGB(HEADER[3], 0, 0) }; break; } } // Search header or use the BytesPeerLine for (int y = 0; y < array.Height; y++) { int index; if ((ImageMode == EImageMode.BlackAndWhite && SearchBytes(array.DataBN[y], bnHeader, out index)) || (ImageMode == EImageMode.RGB && SearchBytes(array.DataRGB[y], rgbHeader, out index))) { array.IndexOfY = y; array.CurrentY = y; array.IndexOfX = array.CurrentX = index; if (ImageMode == EImageMode.BlackAndWhite) { array.CurrentX += bnHeader.Length; } else { BitData.RGB[] row = array.DataRGB[y]; BitData.RGB cur = row[array.IndexOfX + 1]; array.ExtraRGB.AddRange(new byte[] { cur.G, cur.B }); array.CurrentX += 2; } // First frame if (step == 0) { byte[] b = new byte[2]; if (!array.ReadByte(out b[0]) || !array.ReadByte(out b[1])) { extra = array.ExtraBN; return(ms.ToArray()); } max = BitConverter.ToUInt16(b, 0); if (!array.ReadByte(out b[0]) || !array.ReadByte(out b[1])) { extra = array.ExtraBN; return(ms.ToArray()); } array.Width = width = BitConverter.ToUInt16(b, 0); if (!array.ReadByte(out b[0]) || !array.ReadByte(out b[1])) { extra = array.ExtraBN; return(ms.ToArray()); } array.Height = height = BitConverter.ToUInt16(b, 0); b = new byte[4]; if (!array.ReadByte(out b[0]) || !array.ReadByte(out b[1]) || !array.ReadByte(out b[2]) || !array.ReadByte(out b[3])) { extra = array.ExtraBN; return(ms.ToArray()); } array.Length = length = BitConverter.ToUInt32(b, 0); } else { array.Length = length; array.Width = width; array.Height = height; } break; } } if (array.Length == 0) { extra = array.ExtraBN; return(ms.ToArray()); } byte r; while (array.Length > 0) { if (!array.ReadByte(out r)) { break; } ms.WriteByte(r); array.Length--; } length = array.Length; extra = array.ExtraBN; return(ms.ToArray()); } }