Esempio n. 1
0
    /// <summary>
    /// Attempts to read 16 bytes of the stream.
    /// </summary>
    internal static ActlChunk Read(Stream stream)
    {
        var chunk = new ActlChunk
        {
            Length    = BitHelper.ConvertEndian(stream.ReadUInt32()), //Chunk length, 4 bytes.
            ChunkType = Encoding.ASCII.GetString(stream.ReadBytes(4)) //Chunk type, 4 bytes.
        };

        //If the second chunk is not the animation control (acTL), it means that this is a normal PNG.
        if (chunk.ChunkType != "acTL")
        {
            return(null);
        }

        //var pos = stream.Position;
        //chunk.ChunkData = stream.ReadBytes(chunk.Length);
        //stream.Position = pos;

        //Chunk details + CRC, 8 bytes + 4 bytes.
        chunk.NumFrames = BitHelper.ConvertEndian(stream.ReadUInt32());
        chunk.NumPlays  = BitHelper.ConvertEndian(stream.ReadUInt32());
        chunk.Crc       = BitHelper.ConvertEndian(stream.ReadUInt32());

        return(chunk);
    }
Esempio n. 2
0
        internal bool ReadFrames()
        {
            //Png header, 8 bytes.
            if (!InternalStream.ReadBytes(8).SequenceEqual(new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 }))
            {
                throw new Exception("Invalid file format, expected PNG signature not found.");
            }

            //IHDR chunk, 25 bytes.
            Ihdr = IhdrChunk.Read(InternalStream);

            //aCTl chunk, 16 bytes.
            Actl = ActlChunk.Read(InternalStream);

            //If there's no animation control chunk, it's a normal Png.
            if (Actl == null)
            {
                return(false);
            }

            var masterSequence = 0;
            var frameGroupId   = -1;

            //Read frames.
            while (InternalStream.CanRead)
            {
                //Tries to read any chunk, except IEND.
                var chunk = Chunk.Read(InternalStream, masterSequence++);

                //End reached, prematurely or not.
                if (chunk == null || chunk.ChunkType == "IEND")
                {
                    break;
                }

                //Chunks can be grouped into frames.
                if (new[] { "fcTL", "fdAT", "IDAT" }.Contains(chunk.ChunkType))
                {
                    if (chunk.ChunkType == "fcTL")
                    {
                        frameGroupId++;
                    }

                    chunk.FrameGroupId = frameGroupId;
                }

                Chunks.Add(chunk);
            }

            return(true);
        }