Example #1
0
        /// <summary>
        /// Embeds a given watermark into a PNG file and saves the result.
        /// </summary>
        /// <param name="file">PNGFile to use in the watermarking process.</param>
        /// <param name="mark">The watermark to embed.</param>
        /// <param name="password">A password for the embedding process</param>
        /// <param name="outputPath">Location of the saved file.</param>
        public static void EmbedWatermark(PNGFile file, Watermark mark, string password, string outputPath)
        {
            Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(password, new byte[] { 112, 52, 63, 42, 180, 121, 53, 27 }, 1000);

            PNGScrambler scrambler = new PNGScrambler(file, bytes.GetBytes(16), bytes.GetBytes(8));

            byte[] markBytes = mark.GetBytes();

            if (ReedSolomonProtection == false)
            {
                EmbedData(markBytes, scrambler);
            }
            else
            {
                markBytes = EncodeWithReedSolomon(markBytes);
                EmbedData(markBytes, scrambler);
            }

            file.SaveAs(outputPath);
        }
Example #2
0
        private static byte[] ReadBytes(PNGFile file, PNGScrambler scrambler, int count, int skip = 0)
        {
            scrambler.Reset();

            List <byte> bits          = new List <byte>();
            int         numBitsToRead = count * 8;
            int         pixelsToRead  = numBitsToRead / 6 + ((numBitsToRead / 6.0) % 1.0 != 0 ? 1 : 0);

            int pixelsToSkip = (skip * 8) / 6;
            //int bitPairsToThrowaway = pixelsToSkip == 0 ? 0 : (6 - ((skip * 8) % 6)) / 2;
            int bitPairsToThrowaway = ((skip * 8) % 6) / 2;

            if (bitPairsToThrowaway == 2)
            {
                pixelsToRead++;
            }

            for (var x = 0; x < pixelsToSkip; x++)
            {
                scrambler.GetPixel();
            }

            for (var x = 0; x < pixelsToRead; x++)
            {
                PNGPixel p = scrambler.GetPixel();
                bits.Add((byte)(p.Red & 0x03));
                bits.Add((byte)(p.Green & 0x03));
                bits.Add((byte)(p.Blue & 0x03));
            }

            for (var x = 0; x < bitPairsToThrowaway; x++)
            {
                bits.RemoveAt(0);
            }

            return(BitsToBytes(bits));
        }
Example #3
0
        /// <summary>
        /// Extracts a stored watermark from a PNGFile.
        /// </summary>
        /// <param name="file">PNGFile that contains the watermark.</param>
        /// <param name="mark">An empty watermark that will be populated.</param>
        /// <param name="password">Password that was used to embed the watermark.</param>
        /// <returns></returns>
        public static Watermark ExtractWatermark(PNGFile file, string password)
        {
            Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(password, new byte[] { 112, 52, 63, 42, 180, 121, 53, 27 }, 1000);

            PNGScrambler scrambler = new PNGScrambler(file, bytes.GetBytes(16), bytes.GetBytes(8));

            byte[] data = null;
            byte   markType;

            if (ReedSolomonProtection == false)
            {
                byte[] type = ReadBytes(file, scrambler, 1);
                markType = type[0];

                if (markType > 9)
                {
                    return(null);
                }
                byte[] dword  = ReadBytes(file, scrambler, 4, 1);
                int    length = BitConverter.ToInt32(dword, 0);

                try
                {
                    data = ReadBytes(file, scrambler, length, 5);
                }
                catch (Exception e) { return(null); }
            }
            else
            {
                byte[] rsType = ReadBytes(file, scrambler, 3, 0);
                byte[] type   = correctErrors(rsType, 1);
                markType = type[0];
                if ((markType & 0x80) != 0x80)
                {
                    return(null);
                }
                markType ^= 0x80;

                byte[] rsLength   = ReadBytes(file, scrambler, 12, 3);
                byte[] length     = correctErrors(rsLength, 4);
                int    markLength = BitConverter.ToInt32(length, 0);

                int position  = 0;
                int numBlocks = (markLength / 256) + (markLength % 256 > 0 ? 1 : 0);

                MemoryStream msOut = new MemoryStream();

                while (numBlocks > 0)
                {
                    int bytesInBlock = (markLength - (position / 2) < 256 ? markLength - (position / 2) : 256);

                    bytesInBlock *= 2;

                    byte[] codeBytes = ReadBytes(file, scrambler, bytesInBlock, position + 15);

                    byte[] fixedData = correctErrors(codeBytes, bytesInBlock / 2);

                    msOut.Write(fixedData, 0, fixedData.Length);
                    numBlocks--;
                    position += bytesInBlock;
                }

                data = msOut.ToArray();
            }

            Watermark mark = null;

            switch (markType)
            {
            case 1:
                mark = TextWatermark.LoadFromBytes(data);
                break;

            case 2:
                mark = FileWatermark.LoadFromBytes(data);
                break;

            case 3:
                mark = BinaryWatermark.LoadFromBytes(data);
                break;

            case 4:
                mark = CompositeWatermark.LoadFromBytes(data);
                break;

            case 9:
                mark = EncryptedWatermark.LoadFromBytes(data);
                break;
            }

            return(mark);
        }