Beispiel #1
0
        public static async Task <Bitmap> Encode(Bitmap carrierImage, byte[] message, string password, Func <double, bool> checkCancel = null)
        {
            var shuffleSeed = FisherYates.GetSeed(password);

            var messageAsBitArray = message.ConvertToBitArray();

            var userCancelled = false;

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            await Task.Run(() => // move away from the calling thread while working
            {
                var bitsWritten = 0;
                IterateBitmap(carrierImage, shuffleSeed, (x, y) => {
                    EncodePixel(carrierImage, messageAsBitArray, ref bitsWritten, x, y);

                    var percentComplete = ((double)bitsWritten / messageAsBitArray.Length);
                    userCancelled       = checkCancel == null ? false : CheckCancelAndUpdate(stopwatch, percentComplete, checkCancel);

                    bool encodeComplete = bitsWritten >= messageAsBitArray.Length;
                    return(userCancelled || encodeComplete);
                });
            });

            return(userCancelled ? null : carrierImage);
        }
Beispiel #2
0
        private static void IterateBitmap(Bitmap bitmap, int shuffleSeed, Func <int, int, bool> onPixel)
        {
            var shuffledIndices = FisherYates.Shuffle(shuffleSeed, bitmap.Height * bitmap.Width);

            for (var i = 0; i < shuffledIndices.Length; i++)
            {
                var(x, y) = bitmap.Get2DCoordinate(shuffledIndices[i]);

                var done = onPixel(x, y);
                if (done)
                {
                    break;
                }
            }
        }
Beispiel #3
0
        public static async Task <byte[]> Take(Bitmap carrierImage, string password, int startingByteIndex, Int64 bytesToTake, Func <double, bool> checkCancel = null)
        {
            var shuffleSeed = FisherYates.GetSeed(password);

            bool userCancelled = false;

            List <bool> messageBuilder = new List <bool>();

            int startingIndexInBits = startingByteIndex * 8;
            int bitsToTake          = (int)bytesToTake * 8;

            var userUpdateStopwatch = new Stopwatch();
            var eofStopwatch        = new Stopwatch();

            userUpdateStopwatch.Start();
            eofStopwatch.Start();

            await Task.Run(() => // move away from the calling thread while working
            {
                IterateBitmap(carrierImage, shuffleSeed, (x, y) =>
                {
                    var pixelBits = DecodePixel(carrierImage, x, y);
                    messageBuilder.AddRange(pixelBits);

                    var recoveredAllBits = messageBuilder.Count >= startingIndexInBits + bitsToTake;
                    var percentComplete  = (double)messageBuilder.Count / carrierImage.BitCapacity;
                    userCancelled        = checkCancel == null ? false : CheckCancelAndUpdate(userUpdateStopwatch, percentComplete, checkCancel);

                    return(recoveredAllBits || userCancelled);
                });
            });

            messageBuilder.RemoveRange(0, startingIndexInBits);
            messageBuilder = messageBuilder.Take(bitsToTake).ToList(); // TODO: does this ever blow up if the image is ..small? or something. ...on encode it can check. here we could get an error?
            return(messageBuilder.ConvertToByteArray());
        }