/// <summary> /// Применение метода широкополосного сигнала /// Извлечение данных из графического файла /// </summary> /// <param name="bbsOptions">Параметры алгоритма включая графический файл с внедрёнными данными</param> /// <returns>Извлечённые данные</returns> public static string Unpack(BbsOptions bbsOptions) { Debug.WriteLine(bbsOptions.ToString()); string key = bbsOptions.Key; int expandSize = bbsOptions.ExpandSize; int codeSize = bbsOptions.EccCodeSize; int dataSize = bbsOptions.EccDataSize; int filterStep = bbsOptions.FilterStep; int eccIndex = bbsOptions.EccIndex; int mixerIndex = bbsOptions.MixerIndex; int gammaIndex = bbsOptions.GammaIndex; int archiverIndex = bbsOptions.ArchiverIndex; int alpha = bbsOptions.Alpha; int betta = 0; bool autoAlpha = bbsOptions.AutoAlpha; bool maximumGamma = bbsOptions.MaximumGamma; bool extractBarcode = bbsOptions.ExtractBarcode; CvBitmap bitmap = bbsOptions.InputBitmap; if (extractBarcode) { using (var barcode = new Barcode(bitmap.Bitmap)) { // Извлечение параметров из внедрённого в изображение баркода // и использование этих извлечённых параметров для используемых алгоритмов barcode.Decode(); archiverIndex = barcode.ArchiverIndex; eccIndex = barcode.EccIndex; mixerIndex = barcode.MixerIndex; gammaIndex = barcode.GammaIndex; expandSize = barcode.ExpandSize; codeSize = barcode.EccCodeSize; dataSize = barcode.EccDataSize; maximumGamma = barcode.MaximumGamma; key = barcode.Key; } } using (var builder = new BlurBuilder(filterStep)) bbsOptions.MedianBitmap = new CvBitmap(bitmap, builder); CvBitmap median = bbsOptions.MedianBitmap; long length = bitmap.Length; var index = new int[length]; var colors = new byte[length]; var medianColors = new byte[length]; var data = new byte[length / expandSize / BitsPerByte]; using (var builder = new Mixer(mixerIndex, key)) builder.GetInts(index); var gamma = new byte[maximumGamma ? ((length + BitsPerByte - 1) / BitsPerByte) : ((expandSize + BitsPerByte - 1) / BitsPerByte)]; using (var builder = new Gamma(gammaIndex, key)) builder.GetBytes(gamma); bitmap.Select(index, colors); median.Select(index, medianColors); if (autoAlpha) { double e1 = colors.Zip(medianColors, (x, y) => (int)x - (int)y).Average(x => (double)x); double e2 = colors.Zip(medianColors, (x, y) => (int)x - (int)y).Average(x => (double)x * x); betta = (int)e1; alpha = (int)Math.Sqrt(e2 - e1 * e1); bbsOptions.Alpha = alpha; } using (var bbSignals = new BbSignals(expandSize, maximumGamma)) bbSignals.Extract(colors, medianColors, gamma, alpha, betta, data); Debug.WriteLine(string.Join("", data.Select(x => x.ToString("X02")))); // В дополнение к самому методу широкополосного сигнала данные могут быть сжаты алгоритмом компрессии данных, // добавлены коды исправления ошибок, последовательности бит могут размещаться в изображении не последовательно, а в // соответствии с выбранным алгоритмом. IStreamTransform[] streamTransforms = { new Ecc(eccIndex, codeSize, dataSize), // Алгоритм коррекции ошибок new Envelope(), // Извлечение из конверта new Archiver(archiverIndex) // Алгоритм извлечения из сжатого архива }; var input = new MemoryStream(data); Debug.WriteLine("input {0}", input.Length); foreach (IStreamTransform transform in streamTransforms) { using (MemoryStream prev = input) transform.Backward(prev, input = new MemoryStream()); input.Seek(0, SeekOrigin.Begin); Debug.WriteLine("{0} {1}", transform, input.Length); } using (var reader = new BinaryReader(input)) { byte[] bytes = reader.ReadBytes((int)input.Length); Debug.WriteLine(string.Join("", bytes.Select(x => x.ToString("X02")))); return(bbsOptions.RtfText = Encoding.Default.GetString(bytes)); } }
/// <summary> /// Применение метода широкополосного сигнала /// Извлечение данных из графического файла /// </summary> /// <param name="bbsOptions">Параметры алгоритма включая графический файл с внедрёнными данными</param> /// <returns>Извлечённые данные</returns> public static string Unpack(BbsOptions bbsOptions) { Debug.WriteLine(bbsOptions.ToString()); var key = bbsOptions.Key; var expandSize = bbsOptions.ExpandSize; var codeSize = bbsOptions.EccCodeSize; var dataSize = bbsOptions.EccDataSize; var filterStep = bbsOptions.FilterStep; var eccIndex = bbsOptions.EccIndex; var mixerIndex = bbsOptions.MixerIndex; var gammaIndex = bbsOptions.GammaIndex; var archiverIndex = bbsOptions.ArchiverIndex; var zipperIndex = bbsOptions.ZipperIndex; double alpha = bbsOptions.Alpha; double betta = 0; var dhtMode = bbsOptions.DhtMode; var autoAlpha = bbsOptions.AutoAlpha; var maximumGamma = bbsOptions.MaximumGamma; var extractBarcode = bbsOptions.ExtractBarcode; var bitmap = bbsOptions.InputBitmap; if (extractBarcode) { using (var barcode = new Barcode(bitmap.Bitmap)) { // Извлечение параметров из внедрённого в изображение баркода // и использование этих извлечённых параметров для используемых алгоритмов barcode.Decode(); archiverIndex = barcode.ArchiverIndex; eccIndex = barcode.EccIndex; mixerIndex = barcode.MixerIndex; gammaIndex = barcode.GammaIndex; // ints expandSize = barcode.ExpandSize; codeSize = barcode.EccCodeSize; dataSize = barcode.EccDataSize; // bools dhtMode = barcode.DhtMode; autoAlpha = barcode.AutoAlpha; maximumGamma = barcode.MaximumGamma; // strings key = barcode.Key; Debug.WriteLine(barcode.ToString()); } } using (var builder = new BlurBuilder(filterStep)) bbsOptions.MedianBitmap = new CvBitmap(bitmap, builder); var median = bbsOptions.MedianBitmap; var length = bitmap.Length; var index = new int[length]; var colors = new double[length]; var medianColors = new double[length]; var data = new byte[length / expandSize / BitsPerByte]; using (var builder = new Mixer(mixerIndex, key)) builder.GetInts(index); var gamma = new byte[maximumGamma ? ((length + BitsPerByte - 1) / BitsPerByte) : ((expandSize + BitsPerByte - 1) / BitsPerByte)]; using (var builder = new Gamma(gammaIndex, key)) builder.GetBytes(gamma); var bitmapDataContainer = dhtMode ? new HartleyOfBitmap(bitmap) : (IDataContainer)bitmap; bitmapDataContainer.Select(index, colors); var medianDataContainer = dhtMode ? new HartleyOfBitmap(median) : (IDataContainer)median; medianDataContainer.Select(index, medianColors); Debug.Assert(dhtMode || colors.All(x => x >= 0)); Debug.Assert(dhtMode || medianColors.All(x => x >= 0)); // Рассчёт весов пикселей var middle = medianColors.Average(); var weight = medianColors.Select(x => F / (F + Math.Abs(x - middle))).ToArray(); var average = weight.Average(); weight = weight.Select(x => x / average).ToArray(); var delta = colors.Zip(medianColors, (x, y) => (x - y)).Zip(weight, (x, y) => x * y).ToArray(); if (autoAlpha) { // Вычисление параметров из характеристик полученных данных var e1 = delta.Average(x => x); var e2 = delta.Average(x => x * x); betta = e1; bbsOptions.Alpha = (int)Math.Ceiling(alpha = Math.Sqrt(e2 - e1 * e1)); Debug.WriteLine("alpha = {0} betta = {1}", alpha, betta); } using (var bbSignals = new BbSignals(expandSize, maximumGamma)) bbSignals.Extract(delta, data, gamma, alpha, betta); Debug.WriteLine(string.Join("", data.Select(x => x.ToString("X02")))); // В дополнение к самому методу широкополосного сигнала данные могут быть сжаты алгоритмом компрессии данных, // добавлены коды исправления ошибок, последовательности бит могут размещаться в изображении не последовательно, а в // соответствии с выбранным алгоритмом. IStreamTransform[] streamTransforms = { new Ecc(eccIndex, codeSize, dataSize), // Алгоритм коррекции ошибок new Envelope(), // Извлечение из конверта new Archiver(archiverIndex) // Алгоритм извлечения из сжатого архива }; var input = new MemoryStream(data); Debug.WriteLine("input {0}", input.Length); foreach (var transform in streamTransforms) { using (var prev = input) transform.Backward(prev, input = new MemoryStream()); input.Seek(0, SeekOrigin.Begin); Debug.WriteLine("{0} {1}", transform, input.Length); } using (var reader = new BinaryReader(input)) { var bytes = reader.ReadBytes((int)input.Length); Debug.WriteLine(string.Join("", bytes.Select(x => x.ToString("X02")))); return(bbsOptions.RtfText = Encoding.GetEncoding(0).GetString(bytes)); } }
/// <summary> /// Применение метода широкополосного сигнала /// Извлечение данных из графического файла /// </summary> /// <param name="bbsOptions">Параметры алгоритма включая графический файл с внедрёнными данными</param> /// <returns>Извлечённые данные</returns> public static string Unpack(BbsOptions bbsOptions) { Debug.WriteLine(bbsOptions.ToString()); string key = bbsOptions.Key; int expandSize = bbsOptions.ExpandSize; int codeSize = bbsOptions.EccCodeSize; int dataSize = bbsOptions.EccDataSize; int filterStep = bbsOptions.FilterStep; int eccIndex = bbsOptions.EccIndex; int mixerIndex = bbsOptions.MixerIndex; int gammaIndex = bbsOptions.GammaIndex; int archiverIndex = bbsOptions.ArchiverIndex; int alpha = bbsOptions.Alpha; int betta = 0; bool autoAlpha = bbsOptions.AutoAlpha; bool maximumGamma = bbsOptions.MaximumGamma; bool extractBarcode = bbsOptions.ExtractBarcode; CvBitmap bitmap = bbsOptions.InputBitmap; if (extractBarcode) using (var barcode = new Barcode(bitmap.Bitmap)) { // Извлечение параметров из внедрённого в изображение баркода // и использование этих извлечённых параметров для используемых алгоритмов barcode.Decode(); archiverIndex = barcode.ArchiverIndex; eccIndex = barcode.EccIndex; mixerIndex = barcode.MixerIndex; gammaIndex = barcode.GammaIndex; expandSize = barcode.ExpandSize; codeSize = barcode.EccCodeSize; dataSize = barcode.EccDataSize; maximumGamma = barcode.MaximumGamma; key = barcode.Key; } using (var builder = new BlurBuilder(filterStep)) bbsOptions.MedianBitmap = new CvBitmap(bitmap, builder); CvBitmap median = bbsOptions.MedianBitmap; long length = bitmap.Length; var index = new int[length]; var colors = new byte[length]; var medianColors = new byte[length]; var data = new byte[length/expandSize/BitsPerByte]; using (var builder = new Mixer(mixerIndex, key)) builder.GetInts(index); var gamma = new byte[maximumGamma ? ((length + BitsPerByte - 1)/BitsPerByte) : ((expandSize + BitsPerByte - 1)/BitsPerByte)]; using (var builder = new Gamma(gammaIndex, key)) builder.GetBytes(gamma); bitmap.Select(index, colors); median.Select(index, medianColors); if (autoAlpha) { double e1 = colors.Zip(medianColors, (x, y) => (int) x - (int) y).Average(x => (double) x); double e2 = colors.Zip(medianColors, (x, y) => (int) x - (int) y).Average(x => (double) x*x); betta = (int) e1; alpha = (int) Math.Sqrt(e2 - e1*e1); bbsOptions.Alpha = alpha; } using (var bbSignals = new BbSignals(expandSize, maximumGamma)) bbSignals.Extract(colors, medianColors, gamma, alpha, betta, data); Debug.WriteLine(string.Join("", data.Select(x => x.ToString("X02")))); // В дополнение к самому методу широкополосного сигнала данные могут быть сжаты алгоритмом компрессии данных, // добавлены коды исправления ошибок, последовательности бит могут размещаться в изображении не последовательно, а в // соответствии с выбранным алгоритмом. IStreamTransform[] streamTransforms = { new Ecc(eccIndex, codeSize, dataSize), // Алгоритм коррекции ошибок new Envelope(), // Извлечение из конверта new Archiver(archiverIndex) // Алгоритм извлечения из сжатого архива }; var input = new MemoryStream(data); Debug.WriteLine("input {0}", input.Length); foreach (IStreamTransform transform in streamTransforms) { using (MemoryStream prev = input) transform.Backward(prev, input = new MemoryStream()); input.Seek(0, SeekOrigin.Begin); Debug.WriteLine("{0} {1}", transform, input.Length); } using (var reader = new BinaryReader(input)) { byte[] bytes = reader.ReadBytes((int) input.Length); Debug.WriteLine(string.Join("", bytes.Select(x => x.ToString("X02")))); return bbsOptions.RtfText = Encoding.Default.GetString(bytes); } }