Stores header information about a chunk.
예제 #1
0
        private int ReadChunkLength(PngChunk chunk)
        {
            byte[] lengthBuffer = new byte[4];

            int numBytes = _stream.Read(lengthBuffer, 0, 4);

            //if (numBytes.IsBetween(1, 3))
            if (numBytes >= 1 && numBytes <= 3)
            {
                throw new ImageFormatException("Image stream is not valid!");
            }

            Array.Reverse(lengthBuffer);

            chunk.Length = BitConverter.ToInt32(lengthBuffer, 0);

            return(numBytes);
        }
예제 #2
0
        private byte[] ReadChunkType(PngChunk chunk)
        {
            byte[] typeBuffer = new byte[4];

            int numBytes = _stream.Read(typeBuffer, 0, 4);

            if (numBytes.IsBetween(1, 3))
            {
                throw new ImageFormatException("Image stream is not valid!");
            }

            char[] chars = new char[4];
            chars[0] = (char)typeBuffer[0];
            chars[1] = (char)typeBuffer[1];
            chars[2] = (char)typeBuffer[2];
            chars[3] = (char)typeBuffer[3];

            chunk.Type = new string(chars);

            return(typeBuffer);
        }
예제 #3
0
        private void ReadChunkData(PngChunk chunk)
        {
            chunk.Data = new byte[chunk.Length];

            _stream.Read(chunk.Data, 0, chunk.Length);
        }
예제 #4
0
        /// <summary>
        /// Decodes the image from the specified stream and sets
        /// the data to image.
        /// </summary>
        /// <param name="image">The image, where the data should be set to.
        /// Cannot be null (Nothing in Visual Basic).</param>
        /// <param name="stream">The stream, where the image should be
        /// decoded from. Cannot be null (Nothing in Visual Basic).</param>
        /// <exception cref="ArgumentNullException">
        ///     <para><paramref name="image"/> is null (Nothing in Visual Basic).</para>
        ///     <para>- or -</para>
        ///     <para><paramref name="stream"/> is null (Nothing in Visual Basic).</para>
        /// </exception>
        public void Decode(ExtendedImage image, Stream stream)
        {
            _image = image;

            _stream = stream;
            _stream.Seek(8, SeekOrigin.Current);

            bool isEndChunckReached = false;

            PngChunk currentChunk = null;

            byte[] palette      = null;
            byte[] paletteAlpha = null;

            using (MemoryStream dataStream = new MemoryStream())
            {
                while ((currentChunk = ReadChunk()) != null)
                {
                    if (isEndChunckReached)
                    {
                        throw new ImageFormatException("Image does not end with end chunk.");
                    }

                    if (currentChunk.Type == PngChunkTypes.Header)
                    {
                        ReadHeaderChunk(currentChunk.Data);

                        ValidateHeader();
                    }
                    else if (currentChunk.Type == PngChunkTypes.Physical)
                    {
                        ReadPhysicalChunk(currentChunk.Data);
                    }
                    else if (currentChunk.Type == PngChunkTypes.Data)
                    {
                        dataStream.Write(currentChunk.Data, 0, currentChunk.Data.Length);
                    }
                    else if (currentChunk.Type == PngChunkTypes.Palette)
                    {
                        palette = currentChunk.Data;
                    }
                    else if (currentChunk.Type == PngChunkTypes.PaletteAlpha)
                    {
                        paletteAlpha = currentChunk.Data;
                    }
                    else if (currentChunk.Type == PngChunkTypes.Text)
                    {
                        ReadTextChunk(currentChunk.Data);
                    }
                    else if (currentChunk.Type == PngChunkTypes.End)
                    {
                        isEndChunckReached = true;
                    }
                }

                byte[] pixels = new byte[_header.Width * _header.Height * 4];

                PngColorTypeInformation colorTypeInformation = _colorTypes[_header.ColorType];

                if (colorTypeInformation != null)
                {
                    IColorReader colorReader = colorTypeInformation.CreateColorReader(palette, paletteAlpha);

                    ReadScanlines(dataStream, pixels, colorReader, colorTypeInformation);
                }

                image.SetPixels(_header.Width, _header.Height, pixels);
            }
        }
예제 #5
0
        private int ReadChunkLength(PngChunk chunk)
        {
            byte[] lengthBuffer = new byte[4];

            int numBytes = _stream.Read(lengthBuffer, 0, 4);
            if (numBytes.IsBetween(1, 3))
            {
                throw new ImageFormatException("Image stream is not valid!");
            }

            Array.Reverse(lengthBuffer);

            chunk.Length = BitConverter.ToInt32(lengthBuffer, 0);

            return numBytes;
        }
예제 #6
0
        private byte[] ReadChunkType(PngChunk chunk)
        {
            byte[] typeBuffer = new byte[4];

            int numBytes = _stream.Read(typeBuffer, 0, 4);
            if (numBytes.IsBetween(1, 3))
            {
                throw new ImageFormatException("Image stream is not valid!");
            }

            char[] chars = new char[4];
            chars[0] = (char)typeBuffer[0];
            chars[1] = (char)typeBuffer[1];
            chars[2] = (char)typeBuffer[2];
            chars[3] = (char)typeBuffer[3];

            chunk.Type = new string(chars);

            return typeBuffer;
        }
예제 #7
0
        private void ReadChunkData(PngChunk chunk)
        {
            chunk.Data = new byte[chunk.Length];

            _stream.Read(chunk.Data, 0, chunk.Length);
        }
예제 #8
0
        private void ReadChunkCrc(PngChunk chunk, byte[] typeBuffer)
        {
            byte[] crcBuffer = new byte[4];

            int numBytes = _stream.Read(crcBuffer, 0, 4);
            if (numBytes.IsBetween(1, 3))
            {
                throw new ImageFormatException("Image stream is not valid!");
            }

            Array.Reverse(crcBuffer);

            chunk.Crc = BitConverter.ToUInt32(crcBuffer, 0);

            Crc32 crc = new Crc32();
            crc.Update(typeBuffer);
            crc.Update(chunk.Data);

            if (crc.Value != chunk.Crc)
            {
                throw new ImageFormatException("CRC Error. PNG Image chunk is corrupt!");
            }
        }
예제 #9
0
        private PngChunk ReadChunk()
        {
            PngChunk chunk = new PngChunk();

            if (ReadChunkLength(chunk) == 0)
            {
                return null;
            }

            byte[] typeBuffer = ReadChunkType(chunk);

            ReadChunkData(chunk);
            ReadChunkCrc(chunk, typeBuffer);

            return chunk;
        }
예제 #10
0
        private void ReadChunkCrc(PngChunk chunk, byte[] typeBuffer)
        {
            byte[] crcBuffer = new byte[4];

            int numBytes = _stream.Read(crcBuffer, 0, 4);
            //if (numBytes.IsBetween(1, 3))
            if (numBytes >= 1 && numBytes <= 3)
            {
                throw new ImageFormatException("Image stream is not valid!");
            }

            Array.Reverse(crcBuffer);

            chunk.Crc = BitConverter.ToUInt32(crcBuffer, 0);

            //Crc32 crc = new Crc32();
            //crc.Update(typeBuffer);
            //crc.Update(chunk.Data);
            CRC32Calculator crc32Cal = new CRC32Calculator();
            crc32Cal.SlurpBlock(typeBuffer);
            crc32Cal.SlurpBlock(chunk.Data);
            //if (crc.Value != chunk.Crc)
            if ((uint)crc32Cal.Crc32Result != chunk.Crc)
            {
                throw new ImageFormatException("CRC Error. PNG Image chunk is corrupt!");
            }
        }