/// <summary> /// Embeds the text message in image. /// </summary> /// @Precondition none /// @Postcondition the message is embedded into the image /// <param name="messageData">The message data.</param> /// <param name="messageLength">Length of the message.</param> /// <param name="messageImageHeight">Height of the message image.</param> /// <param name="sourceImageWidth">Width of the source image.</param> /// <param name="sourceImageHeight">Height of the source image.</param> /// <param name="encryptionIsChecked">if set to <c>true</c> [encryption is selected].</param> /// <param name="bpcc">The BPCC.</param> /// <returns>Task</returns> /// <exception cref="NotImplementedException"></exception> public override async Task EmbedMessageInImage(byte[] messageData, uint messageLength, uint messageImageHeight, uint sourceImageWidth, uint sourceImageHeight, bool encryptionIsChecked, int bpcc) { var totalAvailableSourcePixels = sourceImageWidth * sourceImageHeight - 2; this.currentByteIndex = 0; var numberOfBits = messageData.Length * this.numberOfBitsInByte; if (numberOfBits / bpcc > totalAvailableSourcePixels * PixelConstants.NumberOfColorChannels) { var requiredBpcc = this.calculateBpccRequiredToEmbedText(numberOfBits, totalAvailableSourcePixels); if (requiredBpcc > this.numberOfBitsInByte) { await Dialogs.ShowNotPossibleToEmbedTextDialog(); } else { await Dialogs.ShowRequiredBpccToEmbedTextDialog(requiredBpcc); } MessageTooLarge = true; return; } var currentIndex = 0; for (var currY = 0; currY < sourceImageHeight; currY++) { for (var currX = 0; currX < sourceImageWidth; currX++) { var sourcePixelColor = PixelColorInfo.GetPixelBgra8(SourceImagePixels, currY, currX, sourceImageWidth); if (IsFirstPixel(currX, currY)) { sourcePixelColor = HeaderPixelFormatter.FormatFirstHeaderPixel(sourcePixelColor); } else if (IsSecondPixel(currX, currY)) { sourcePixelColor = HeaderPixelFormatter.FormatSecondHeaderPixel(FileTypes.Text, sourcePixelColor, encryptionIsChecked, bpcc); } else { sourcePixelColor = this.embedTextMessage(messageData, sourcePixelColor, currentIndex, bpcc); currentIndex += PixelConstants.NumberOfColorChannels * bpcc; } PixelColorInfo.SetPixelBgra8(SourceImagePixels, currY, currX, sourcePixelColor, sourceImageWidth); } } await SetEmbeddedImage(sourceImageHeight, sourceImageWidth); }
/// <summary> /// Extracts the message from image. /// </summary> /// @Precondition none /// @postcondition message is extracted from the image /// <param name="embeddedPixels">The embedded pixels.</param> /// <param name="embeddedImageWidth">Width of the embedded image.</param> /// <param name="embeddedImageHeight">Height of the embedded image.</param> public override async Task ExtractMessageFromImage(byte[] embeddedPixels, uint embeddedImageWidth, uint embeddedImageHeight) { for (var currY = 0; currY < embeddedImageHeight; currY++) { for (var currX = 0; currX < embeddedImageWidth; currX++) { var embeddedPixelColor = PixelColorInfo.GetPixelBgra8(embeddedPixels, currY, currX, embeddedImageWidth); if (isFirstPixel(currY, currX)) { if (!(embeddedPixelColor.R == 212 && embeddedPixelColor.B == 212 && embeddedPixelColor.G == 212)) { await Dialogs.ShowNoMessageDialog(); return; } } else if (isSecondPixel(currY, currX)) { EncryptionUsed = (embeddedPixelColor.R & 1) == 0; } else { var currentBlueColorByte = embeddedPixelColor.B; if (isBitSet(currentBlueColorByte, 0)) { embeddedPixelColor = this.whitePixel; } else { embeddedPixelColor = this.blackPixel; } } PixelColorInfo.SetPixelBgra8(embeddedPixels, currY, currX, embeddedPixelColor, embeddedImageWidth); } } ExtractedImage = new WriteableBitmap((int)embeddedImageWidth, (int)embeddedImageHeight); using (var writeStream = ExtractedImage.PixelBuffer.AsStream()) { await writeStream.WriteAsync(embeddedPixels, 0, embeddedPixels.Length); } }
/// <summary> /// Embeds the message in image. /// </summary> /// @Precondition none /// @Postcondition the message is embedded into the image /// <param name="messagePixels">The message pixels.</param> /// <param name="messageImageWidth">Width of the message image.</param> /// <param name="messageImageHeight">Height of the message image.</param> /// <param name="sourceImageWidth">Width of the source image.</param> /// <param name="sourceImageHeight">Height of the source image.</param> /// <param name="encryptionIsChecked">if set to <c>true</c> [encryption is checked].</param> /// <param name="bpcc">The BPCC.</param> public override async Task EmbedMessageInImage(byte[] messagePixels, uint messageImageWidth, uint messageImageHeight, uint sourceImageWidth, uint sourceImageHeight, bool encryptionIsChecked, int bpcc) { this.isEncrypted = encryptionIsChecked; if (messageImageWidth > sourceImageWidth || messageImageHeight > sourceImageHeight) { await Dialogs.ShowMessageFileTooLargeDialog(); MessageTooLarge = true; return; } for (var currY = 0; currY < sourceImageHeight; currY++) { for (var currX = 0; currX < sourceImageWidth; currX++) { var sourcePixelColor = PixelColorInfo.GetPixelBgra8(SourceImagePixels, currY, currX, sourceImageWidth); if (IsFirstPixel(currX, currY)) { sourcePixelColor = HeaderPixelFormatter.FormatFirstHeaderPixel(sourcePixelColor); } else if (IsSecondPixel(currX, currY)) { sourcePixelColor = HeaderPixelFormatter.FormatSecondHeaderPixel(FileTypes.Bitmap, sourcePixelColor, encryptionIsChecked, bpcc); } else { sourcePixelColor = this.embedMonochromeImage(currX, messageImageWidth, currY, messageImageHeight, messagePixels, sourcePixelColor); } PixelColorInfo.SetPixelBgra8(SourceImagePixels, currY, currX, sourcePixelColor, sourceImageWidth); } } await SetEmbeddedImage(sourceImageHeight, sourceImageWidth); }