예제 #1
0
        /// <summary>
        /// Main constructor for PNGFile.
        /// </summary>
        /// <param name="path">Path to the PNG file to be loaded.</param>
        public PNGFile(string path)
        {
            originalFile = path;
            var reader = FileHelper.CreatePngReader(path);

            if (reader.ImgInfo.BitDepth != 8 || reader.ImgInfo.Channels < 3)
            {
                throw new ArgumentException("The PNG file must be an 24/32 bit PNG file, 8bit channels and RGB/A");
            }
            this.ImgInfo             = reader.ImgInfo;
            reader.ShouldCloseStream = true;
            hasAlpha = reader.ImgInfo.Alpha;
            for (var x = 0; x < reader.ImgInfo.Rows; x++)
            {
                PNGPixel[] line = new PNGPixel[reader.ImgInfo.Cols];

                byte[] scanLine = reader.ReadRowByte(x).ScanlineB;

                int      bytesPerPixel = hasAlpha ? 4 : 3;
                int      byteCount     = 0;
                int      pixelCount    = 0;
                PNGPixel curPixel      = new PNGPixel();
                for (var y = 0; y < scanLine.Length; y++)
                {
                    byteCount++;

                    if (byteCount > bytesPerPixel || y == (scanLine.Length - 1))
                    {
                        line[pixelCount++] = curPixel;

                        byteCount = 1;
                        curPixel  = new PNGPixel();
                    }

                    if (byteCount == 1)
                    {
                        curPixel.Red = scanLine[y];
                    }
                    else if (byteCount == 2)
                    {
                        curPixel.Green = scanLine[y];
                    }
                    else if (byteCount == 3)
                    {
                        curPixel.Blue = scanLine[y];
                    }
                    else if (byteCount == 4)
                    {
                        curPixel.Alpha = scanLine[y];
                    }
                }
                lines.Add(line);
            }
            reader.End();
            reader = null;
        }
예제 #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));
        }
예제 #3
0
        private static void EmbedData(byte[] data, PNGScrambler scrambler)
        {
            PNGPixel pix = null;

            List <byte> bits    = BytesToBits(data);
            int         channel = 3;

            for (var x = 0; x < bits.Count; x++)
            {
                if (channel == 3)
                {
                    pix     = scrambler.GetPixel();
                    channel = 0;
                }

                switch (channel)
                {
                case 0:
                    pix.Red &= 0xFC;
                    pix.Red |= bits[x];
                    break;

                case 1:
                    pix.Green &= 0xFC;
                    pix.Green |= bits[x];
                    break;

                case 2:
                    pix.Blue &= 0xFC;
                    pix.Blue |= bits[x];
                    break;
                }

                channel++;
            }
        }