Beispiel #1
0
 /// <summary>
 /// Writes a int value as 2 bytes, but inverted.
 /// 100 = 64 00 instead of 00 64.
 /// </summary>
 /// <param name="value"></param>
 private void WriteShort(int value)
 {
     //Writes the second part first.
     //The "& 0xff" makes sure that the int will stay on range 0-255, it will cut any number above 255.
     InternalStream.WriteByte(Convert.ToByte(value & 0xff));
     InternalStream.WriteByte(Convert.ToByte((value >> 8) & 0xff));
 }
Beispiel #2
0
        /// <inheritdoc/>
        public override long Seek(long offset, SeekOrigin origin)
        {
            switch (origin)
            {
            case SeekOrigin.Begin:
                InternalStream.Seek(startPosition + offset, SeekOrigin.Begin);
                break;

            case SeekOrigin.Current:
                InternalStream.Seek(offset, SeekOrigin.Current);
                break;

            case SeekOrigin.End:
                // Maybe we don't know the actual file size (full file)
                if (endPosition == -1)
                {
                    InternalStream.Seek(offset, SeekOrigin.End);
                }
                else
                {
                    InternalStream.Seek(endPosition - startPosition + offset, SeekOrigin.Begin);
                }
                break;
            }

            var newPosition = InternalStream.Position;

            if (newPosition < startPosition || (endPosition != -1 && newPosition > endPosition))
            {
                InternalStream.Position = startPosition;
                throw new InvalidOperationException("Seek position is out of bound.");
            }

            return(newPosition);
        }
Beispiel #3
0
        private int ParseBitCountAndExpandStreamAsNeeded(int bitCount)
        {
            if (InternalStream.Count == 0)
            {
                InternalStream.Add(0x00);
            }

            int oldPos     = InternalStream.Count - 1;
            int bytesToAdd = 0;

            if ((bitCount + (BitPos - 1)) > Constants.ByteSizeInBits)
            {
                int adjustedBitCount = bitCount - (Constants.ByteSizeInBits - (BitPos - 1));
                bytesToAdd = adjustedBitCount / Constants.ByteSizeInBits;
                if (adjustedBitCount % Constants.ByteSizeInBits != 0)
                {
                    bytesToAdd++;
                }
            }
            if (ForceAddByte)
            {
                bytesToAdd++;
                oldPos++;
            }

            for (int i = 0; i < bytesToAdd; i++)
            {
                InternalStream.Add(0x00);
            }

            ForceAddByte = false;
            return(oldPos);
        }
Beispiel #4
0
 /// <summary>获取用于收发数据的数据流</summary>
 /// <returns></returns>
 public virtual Stream GetStream()
 {
     if (_Stream == null)
     {
         _Stream = new InternalStream(this);
     }
     return(_Stream);
 }
Beispiel #5
0
        /// <inheritdoc/>
        public override int ReadByte()
        {
            if (endPosition != -1 && InternalStream.Position >= endPosition)
            {
                return(-1);
            }

            return(InternalStream.ReadByte());
        }
Beispiel #6
0
        /// <inheritdoc/>
        public override void SetLength(long value)
        {
            if (endPosition != -1)
            {
                throw new InvalidOperationException("Can't resize VirtualFileStream if endPosition is not -1.");
            }

            InternalStream.SetLength(value);
        }
Beispiel #7
0
        /// <inheritdoc/>
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (endPosition != -1 && count > endPosition - InternalStream.Position)
            {
                throw new NotSupportedException("Can't write beyond end of stream.");
            }

            InternalStream.Write(buffer, offset, count);
        }
Beispiel #8
0
 public void Dispose()
 {
     // Complete File
     WriteByte(0x3b);
     // Pushing data
     InternalStream.Flush();
     //Resets the stream position to save afterwards.
     InternalStream.Position = 0;
 }
Beispiel #9
0
        /// <inheritdoc/>
        public override void WriteByte(byte value)
        {
            if (endPosition != -1 && InternalStream.Position >= endPosition)
            {
                throw new NotSupportedException("Can't write beyond end of stream.");
            }

            InternalStream.WriteByte(value);
        }
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (IsDisposeInternalStreamOnDispose)
            {
                InternalStream.DisposeIfNotNull();
            }
        }
Beispiel #11
0
        public void Dispose()
        {
            //Write down the image bytes.

            InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)0)); //Global mask information size, 4 bytes.

            //Aditional info.

            //Precomposed image data?
        }
Beispiel #12
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;
        }
Beispiel #13
0
        public void Dispose()
        {
            //Add a comment section.
            WriteComment("Made with ScreenToGif");

            //Complete the file.
            WriteByte(0x3b);
            //Push data.
            InternalStream.Flush();
            //Resets the stream position to save afterwards.
            InternalStream.Position = 0;
        }
Beispiel #14
0
        public override long Seek(long offset, SeekOrigin origin)
        {
            switch (origin)
            {
            case SeekOrigin.Begin: return(InternalStream.Seek(offset + DataOffset, SeekOrigin.Begin));

            case SeekOrigin.Current: return(InternalStream.Seek(offset, SeekOrigin.Current));

            case SeekOrigin.End: return(InternalStream.Seek(DataOffset + DataLength - offset, SeekOrigin.Begin));

            default: throw new InvalidOperationException();
            }
        }
Beispiel #15
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);
        }
Beispiel #16
0
        /// <inheritdoc/>
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (endPosition != -1)
            {
                var maxCount = (int)(endPosition - InternalStream.Position);
                if (count > maxCount)
                {
                    count = maxCount;
                }
            }

            var bytesProcessed = InternalStream.Read(buffer, offset, count);

            return(bytesProcessed);
        }
Beispiel #17
0
        /// <summary>
        /// Writes the comment for the animation.
        /// </summary>
        /// <param name="comment">The comment to write to the gif.</param>
        private void WriteComment(string comment)
        {
            InternalStream.WriteByte(0x21);
            InternalStream.WriteByte(0xfe);

            //byte[] length = StringToByteArray(comment.Length.ToString("X"));

            //foreach (byte b in length)
            //    fs.WriteByte(b);

            var bytes = System.Text.Encoding.ASCII.GetBytes(comment);

            InternalStream.WriteByte((byte)bytes.Length);
            InternalStream.Write(bytes, 0, bytes.Length);
            InternalStream.WriteByte(0);
        }
Beispiel #18
0
        protected override void Dispose(bool disposing)
        {
            if (virtualFileStream != null)
            {
                virtualFileStream.Dispose();
            }
            virtualFileStream = null;

            if (disposeInternalStream && InternalStream != null)
            {
                InternalStream.Dispose();
            }

            InternalStream = null;
            base.Dispose(disposing);
        }
 public override void SetLength(long value)
 {
     InternalStream.SetLength(value);
 }
 public override void Write(byte[] buffer, int offset, int count)
 {
     InternalStream.Write(buffer, offset, count);
 }
 public override int Read(byte[] buffer, int offset, int count)
 {
     return(InternalStream.Read(buffer, offset, count));
 }
 public override long Seek(long offset, SeekOrigin origin)
 {
     return(InternalStream.Seek(offset, origin));
 }
 public void DisposeInternalStream()
 {
     InternalStream.DisposeIfNotNull();
 }
 public override void Flush()
 {
     InternalStream.Flush();
 }
Beispiel #25
0
 public void Dispose()
 {
     InternalStream?.Dispose();
 }
Beispiel #26
0
 /// <summary>
 /// 获取用于收发数据的数据流
 /// </summary>
 /// <returns></returns>
 public virtual Stream GetStream()
 {
     if (_Stream == null) _Stream = new InternalStream(this);
     return _Stream;
 }
Beispiel #27
0
 private void WriteString(string value)
 {
     InternalStream.Write(value.ToArray().Select(c => (byte)c).ToArray(), 0, value.Length);
 }
Beispiel #28
0
 /// <summary>
 /// Copies the internal buffer of bytes to a new array.
 /// </summary>
 /// <returns>An array of bytes built up from the internal buffer.</returns>
 public byte[] ToArray() => InternalStream.ToArray();
Beispiel #29
0
 private void WriteByte(int value)
 {
     InternalStream.WriteByte(Convert.ToByte(value));
 }
Beispiel #30
0
        internal void Encode()
        {
            //Psd Header: 26 bytes.
            InternalStream.WriteBytes(Encoding.ASCII.GetBytes("8BPS"));        //Chunk type, 4 bytes.
            InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)1));    //File version, 1 - PSD, 2 - PSB, 2 bytes.
            InternalStream.Position += 6;                                      //Must be zero, 6 bytes.
            InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)4));    //Number of channels, ARGB, 2 bytes.
            InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)Height)); //Height of the image, 4 bytes.
            InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)Width));  //Width of the image, 4 bytes.
            InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)8));    //Number of bits per channel, 2 bytes.
            InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)3));    //The color mode of the file, 3 - RGB, 2 bytes.

            //Color mode data. 4 bytes.
            InternalStream.WriteUInt32(BitHelper.ConvertEndian(0u)); //The size of the color mode data block, 0 bytes for RGB mode, 4 bytes.

            //Image resources. XX bytes.
            InternalStream.WriteBytes(ImageResources.Content);

            //LayerAndMaskInformation. 4 + XX bytes.
            var layerAndMask = LayerAndMask.Content;

            InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)layerAndMask.Length)); //Length of the LayerAndMask block, 4 bytes.
            InternalStream.WriteBytes(layerAndMask);                                        //Content of the LayerAndMask block.

            //ImageData. XX bytes.
            if (Compress)
            {
                InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)1)); //The type of encoding, PackBit/RLE, 2 bytes.
                foreach (var layer in LayerAndMask.LayerInfo.ImageChannelDataList)
                {
                    //Writes all byte counts for all the scan lines (rows * channels), with each count stored as a two-byte value.
                    foreach (var channel in layer.ChannelList)
                    {
                        foreach (var b in channel.RleCompressedContent)
                        {
                            InternalStream.WriteInt16(BitHelper.ConvertEndian((short)b.Length));
                        }
                    }

                    //Writes down each layer, in planar order: AAA RRR GGG BBB.
                    foreach (var channel in layer.ChannelList)
                    {
                        foreach (var b in channel.RleCompressedContent)
                        {
                            InternalStream.WriteBytes(b);
                        }
                    }

                    break;
                }
            }
            else
            {
                InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)0)); //The type of encoding, Raw data, 2 bytes.
                foreach (var layer in LayerAndMask.LayerInfo.ImageChannelDataList)
                {
                    //Writes down each layer, in planar order: AAA RRR GGG BBB.
                    foreach (var channel in layer.ChannelList)
                    {
                        InternalStream.WriteBytes(channel.RawContent);
                    }

                    break;
                }
            }
        }
Beispiel #31
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;
            }
        }