private void InputFileChoose_OnFilenameChanged(object sender, EventArgs e) { if (InputImage?.Source == null) { return; } var w = new WriteableBitmap((BitmapSource)InputImage.Source); unsafe { uint * pixel = (uint *)w.BackBuffer; MessageHeader header = new MessageHeader { ChecksumType = new XorChecksumCalculator() }; var headerData = new byte[header.Length]; for (int i = 0; i < headerData.Length; i++) { headerData[i] = ByteHider.RecoverByte(*pixel); pixel++; } try { header = MessageHeader.FromBytes(headerData); } catch (FormatException) { ShowImageInvalidMessage(); return; } pixel++; int startIndex = FillStartUtility.GetFillStartIndex(header.Fill, w.PixelWidth, w.PixelHeight, header.DataLength * (header.DataSpacing + 1)); pixel += startIndex - header.Length - 1; var dataBuffer = new byte[header.DataLength]; for (int i = 0; i < dataBuffer.Length; i++) { dataBuffer[i] = ByteHider.RecoverByte(*pixel); pixel++; // skip spacing pixels for (int j = 0; j < header.DataSpacing; j++) { pixel++; } } // check the checksum var checksumMatches = header.Checksum.SequenceEqual(_checksumCalculator.GetChecksum(dataBuffer)); if (!checksumMatches) { ShowImageInvalidMessage(); } else { OutputTextBox.Text = Encoding.UTF8.GetString(dataBuffer); } } }
private void MessageTextChanged(object sender, TextChangedEventArgs e) { if (OutputImage?.Source == null) { return; } var w = (WriteableBitmap)OutputImage.Source; var textBox = sender as TextBox; IsOverCapacity = false; var data = Encoding.UTF8.GetBytes(textBox.Text); var header = new MessageHeader { Fill = (FillStart)FillComboBox.SelectedIndex, ChecksumType = new XorChecksumCalculator(), DataLength = checked ((ushort)data.Length) }; try { header.DataSpacing = byte.Parse(SpaceTextBox.Text); if (header.DataSpacing > 254) { throw new Exception(); } } catch { MessageBox.Show("Invalid spacing, allowed range is 0-254"); return; } var capacity = Math.Min(ushort.MaxValue, (w.PixelWidth * w.PixelHeight - header.Length) / (header.DataSpacing + 1)); ProgressBar.Maximum = capacity; var textDataLength = Encoding.UTF8.GetByteCount(textBox.Text); ProgressBar.Value = textDataLength; if (textDataLength > capacity) { IsOverCapacity = true; return; } header.SetChecksumFromData(data); int dataStartPixelIndex = FillStartUtility.GetFillStartIndex(header.Fill, w.PixelWidth, w.PixelHeight, data.Length * (header.DataSpacing + 1)); var original = new WriteableBitmap((BitmapSource)InputImage.Source); w.Lock(); long counter = 0; unsafe { uint *originalPixel = (uint *)original.BackBuffer; uint *pixel = (uint *)w.BackBuffer; var headerBytes = header.GetBytes(); // place header bytes foreach (byte b in headerBytes) { *pixel = ByteHider.HideByte(*originalPixel, b); pixel++; originalPixel++; counter++; } // copy unmodified bytes while (counter < dataStartPixelIndex) { *pixel = *originalPixel; pixel++; originalPixel++; counter++; } // place data foreach (byte b in data) { *pixel = ByteHider.HideByte(*originalPixel, b); pixel++; originalPixel++; counter++; // copy spacing pixels for (int i = 0; i < header.DataSpacing; i++) { *pixel = *originalPixel; pixel++; originalPixel++; counter++; } } // copy unmodified bytes while (counter < w.PixelWidth * w.PixelHeight) { *pixel = *originalPixel; pixel++; originalPixel++; counter++; } } w.AddDirtyRect(new Int32Rect(0, 0, w.PixelWidth, w.PixelHeight)); w.Unlock(); }