Пример #1
0
        public void Dispose()
        {
            //IEND: The end of the Png datastream. 0 bytes (Length + Type + CRC, 4 bytes each) = 12 bytes.
            InternalStream.WriteUInt32(BitHelper.ConvertEndian(0u));                                                                            //Length, 4 bytes.
            InternalStream.WriteBytes(Encoding.ASCII.GetBytes("IEND"));                                                                         //Chunk type, 4 bytes.
            InternalStream.WriteUInt32(BitHelper.ConvertEndian(CrcHelper.Calculate(InternalStream.PeekBytes(InternalStream.Position - 4, 4)))); //CRC, 4 bytes.

            InternalStream.Flush();
            //Resets the stream position to save afterwards.
            InternalStream.Position = 0;
        }
Пример #2
0
        internal void AddFrame(string path, Int32Rect rect, int delay = 66)
        {
            using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                if (IsFirstFrame)
                {
                    //Png Header: 8 bytes.
                    InternalStream.WriteBytes(stream.ReadBytes(8));

                    //IHDR chunk. 13 bytes (Length + Type + CRC, 4 bytes each) = 25 bytes.
                    InternalStream.WriteBytes(stream.ReadBytes(25));

                    //acTL: Animation control chunk. 8 bytes (Length + Type + CRC, 4 bytes each) = 20 bytes.
                    InternalStream.WriteUInt32(BitHelper.ConvertEndian(8u));                                                                              //Length, 4 bytes.
                    InternalStream.WriteBytes(Encoding.ASCII.GetBytes("acTL"));                                                                           //Chunk type, 4 bytes.
                    InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)FrameCount));                                                                //NumFrames, 4 bytes.
                    InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)RepeatCount));                                                               //NumPlays, 4 bytes.
                    InternalStream.WriteUInt32(BitHelper.ConvertEndian(CrcHelper.Calculate(InternalStream.PeekBytes(InternalStream.Position - 12, 12)))); //CRC, 4 bytes.
                }

                //fcTL: Frame control chunk. 26 bytes (Length + Type + CRC, 4 bytes each) = 38 bytes.
                InternalStream.WriteUInt32(BitHelper.ConvertEndian(26u));                    //Length, 4 bytes.
                InternalStream.WriteBytes(Encoding.ASCII.GetBytes("fcTL"));                  //Chunk type, 4 bytes.
                InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)SequenceNumber++)); //SequenceNumber, 4 bytes.
                InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)rect.Width));       //Width, 4 bytes.
                InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)rect.Height));      //Height, 4 bytes.
                InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)rect.X));           //OffsetX, 4 bytes.
                InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)rect.Y));           //OffsetY, 4 bytes.
                InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)delay));          //Delay numerator, 2 bytes.
                InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)1000));           //Delay denominator, 2 bytes.

                if (IsFirstFrame)
                {
                    InternalStream.WriteByte((byte)DisposeOps.None); //DisposeOp, 1 byte.
                    InternalStream.WriteByte((byte)BlendOps.Source); //BlendOp, 1 byte.
                }
                else
                {
                    InternalStream.WriteByte((byte)DisposeOps.None); //DisposeOp, 1 byte.
                    InternalStream.WriteByte((byte)BlendOps.Over);   //BlendOp, 1 byte.
                }

                InternalStream.WriteUInt32(BitHelper.ConvertEndian(CrcHelper.Calculate(InternalStream.PeekBytes(InternalStream.Position - 30, 30)))); //CRC, 4 bytes.

                //fdAT: Frame data chunk. 4 + n bytes (Length + Type + CRC, 4 bytes each) = 16 + n bytes, where n is the frame data.
                var dataList = GetData(stream);

                foreach (var data in dataList)
                {
                    if (IsFirstFrame)
                    {
                        InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)data.Length));                                                                                           //Length, 4 bytes.
                        InternalStream.WriteBytes(Encoding.ASCII.GetBytes("IDAT"));                                                                                                       //Chunk type, 4 bytes.
                        InternalStream.WriteBytes(data);                                                                                                                                  //Frame data, n bytes.
                        InternalStream.WriteUInt32(BitHelper.ConvertEndian(CrcHelper.Calculate(InternalStream.PeekBytes(InternalStream.Position - (data.Length + 4), data.Length + 4)))); //CRC, 4 bytes.
                    }
                    else
                    {
                        InternalStream.WriteUInt32(BitHelper.ConvertEndian(4 + (uint)data.Length));                                                                                       //Length, 4 bytes.
                        InternalStream.WriteBytes(Encoding.ASCII.GetBytes("fdAT"));                                                                                                       //Chunk type, 4 bytes.
                        InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)SequenceNumber++));                                                                                      //SequenceNumber, 4 bytes.
                        InternalStream.WriteBytes(data);                                                                                                                                  //Frame data, n bytes.
                        InternalStream.WriteUInt32(BitHelper.ConvertEndian(CrcHelper.Calculate(InternalStream.PeekBytes(InternalStream.Position - (data.Length + 8), data.Length + 8)))); //CRC, 4 bytes.
                    }
                }

                IsFirstFrame = false;
            }
        }