PNGMask.PNG.ProcessStream C# (CSharp) Method

ProcessStream() public method

public ProcessStream ( Stream data ) : void
data Stream
return void
        void ProcessStream(Stream data)
        {
            if (data.CanTimeout) throw new PNGMaskException("Stream must not be able to time-out");
            if (!data.CanRead) throw new PNGMaskException("Stream must be readable");
            if (!data.CanSeek) throw new PNGMaskException("Stream must be seekable");

            if (data.Length < MAGIC_NUMBER.Length) throw new PNGMaskException("File is smaller than magic number");

            byte[] buffer = new byte[MAGIC_NUMBER.Length];
            if (data.Read(buffer, 0, buffer.Length) < buffer.Length) throw new PNGMaskException("Could not read magic number");

            for (int i = 0; i < buffer.Length; i++)
                if (buffer[i] != MAGIC_NUMBER[i]) throw new PNGMaskException("Incorrect magic number, this file is not a PNG.");

            Chunks = new List<PNGChunk>();
            buffer = new byte[4];
            bool first = true;
            string name;
            do
            {
                ReadData(data, ref buffer);
                SwapEndianness(ref buffer);
                uint length = BitConverter.ToUInt32(buffer, 0);

                ReadData(data, ref buffer);
                byte[] nameb = (byte[])buffer.Clone();
                name = Encoding.ASCII.GetString(buffer);
                if (first)
                {
                    if (name != "IHDR") throw new PNGMaskException("First chunk must be IHDR, PNG is corrupt.");
                    if (length < 8) throw new PNGMaskException("IHDR chunk is too small, PNG is corrupt");
                    first = false;
                }

                byte[] chunkdata = new byte[length];
                ReadData(data, ref chunkdata);

                ReadData(data, ref buffer);
                byte[] crcb = (byte[])buffer.Clone();
                SwapEndianness(ref buffer);
                uint CRC = BitConverter.ToUInt32(buffer, 0);

                uint[] crcTable = null;
                uint CRC2 = CRC32(nameb, 0, nameb.Length, 0, ref crcTable);
                CRC2 = CRC32(chunkdata, 0, chunkdata.Length, CRC2, ref crcTable);

                bool standard = false;
                foreach (string s in STANDARD_CHUNKS)
                    if (name == s) { standard = true; break; }

                bool critical = false;
                if (standard)
                    foreach (string s in CRITICAL_CHUNKS)
                        if (name == s) { critical = true; break; }

                Chunks.Add(new PNGChunk()
                {
                    Name = name,
                    Standard = standard,
                    Critical = critical,
                    Data = chunkdata,
                    CRC = CRC,
                    CRCBytes = crcb,
                    ValidCRC = (CRC == CRC2)
                });
            } while (name != "IEND");

            long EOF = data.Length - data.Position;
            if (EOF > 0)
            {
                buffer = new byte[EOF];
                ReadData(data, ref buffer);

                Chunks.Add(new PNGChunk()
                {
                    Name = "_EOF",
                    Standard = false,
                    Critical = false,
                    Data = buffer,
                    CRC = 0,
                    CRCBytes = new byte[] { 0x00, 0x00, 0x00, 0x00 },
                    ValidCRC = false
                });
            }

            PNGChunk IHDR = Chunks[0];

            Width = BitConverter.ToUInt32(new byte[4] { IHDR.Data[3], IHDR.Data[2], IHDR.Data[1], IHDR.Data[0] }, 0);
            Height = BitConverter.ToUInt32(new byte[4] { IHDR.Data[7], IHDR.Data[6], IHDR.Data[5], IHDR.Data[4] }, 0);
        }