/// <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)); }
/// <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); }
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); }
/// <summary>获取用于收发数据的数据流</summary> /// <returns></returns> public virtual Stream GetStream() { if (_Stream == null) { _Stream = new InternalStream(this); } return(_Stream); }
/// <inheritdoc/> public override int ReadByte() { if (endPosition != -1 && InternalStream.Position >= endPosition) { return(-1); } return(InternalStream.ReadByte()); }
/// <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); }
/// <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); }
public void Dispose() { // Complete File WriteByte(0x3b); // Pushing data InternalStream.Flush(); //Resets the stream position to save afterwards. InternalStream.Position = 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(); } }
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? }
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; }
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; }
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(); } }
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); }
/// <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); }
/// <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); }
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(); }
public void Dispose() { InternalStream?.Dispose(); }
/// <summary> /// 获取用于收发数据的数据流 /// </summary> /// <returns></returns> public virtual Stream GetStream() { if (_Stream == null) _Stream = new InternalStream(this); return _Stream; }
private void WriteString(string value) { InternalStream.Write(value.ToArray().Select(c => (byte)c).ToArray(), 0, value.Length); }
/// <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();
private void WriteByte(int value) { InternalStream.WriteByte(Convert.ToByte(value)); }
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; } } }
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; } }