/// <summary> /// Writes the byte representation of this <see cref="GifExtension"/> to the given <see cref="Stream"/>. /// </summary> /// <param name="stream">The <see cref="Stream"/> to write to.</param> internal void WriteToStream(Stream stream) { stream.WriteByte(header); stream.WriteByte(FunctionCode); GifDataStream.Encode(stream, getData()); }
/// <summary> /// Writes the compressed version of the given Color Data to the given <see cref="Stream"/>. /// </summary> /// <param name="stream">The <see cref="Stream"/> to write to.</param> /// <param name="colorData">The Color Data to compress.</param> /// <param name="colorTableSize">Number of entries in the used color table.</param> public static void Encode(Stream stream, IEnumerable <byte> colorData, ushort colorTableSize) { var startCodeSize = (byte)Math.Max(minStartCodeSize, Math.Ceiling(Math.Log(colorTableSize, 2))); if (startCodeSize > maxStartCodeSize) { throw new ArgumentOutOfRangeException("colorTableSize", "Color Table can have a maximum of 256 entries!"); } stream.WriteByte(startCodeSize); using (var codeStream = new BitStream.BitStream(new MemoryStream())) { var codeTable = new Dictionary <CodeTableEntry, ushort>(); buildCodeTable(codeTable, startCodeSize); var codeSize = (byte)(startCodeSize + 1); codeStream.WriteBits(BitConverter.GetBytes(codeTable[CodeTableEntry.Clear]), 0, codeSize); var indexBuffer = new List <byte>(colorData.Take(1)); CodeTableEntry tableEntry = null; foreach (var color in colorData.Skip(1)) { if (codeSize > maxCodeSize) { codeStream.WriteBits(BitConverter.GetBytes(codeTable[CodeTableEntry.Clear]), 0, maxCodeSize); buildCodeTable(codeTable, startCodeSize); codeSize = (byte)(startCodeSize + 1); } var prevIndexBuffer = indexBuffer.ToArray(); indexBuffer.Add(color); tableEntry = CodeTableEntry.MakeColorEntry(indexBuffer.ToArray()); if (codeTable.ContainsKey(tableEntry)) { continue; } codeTable.Add(tableEntry, (ushort)codeTable.Count); var bytes = BitConverter.GetBytes(codeTable[CodeTableEntry.MakeColorEntry(prevIndexBuffer)]); codeStream.WriteBits(bytes, 0, codeSize); indexBuffer.Clear(); indexBuffer.Add(color); if ((Math.Pow(2, codeSize) + 1) <= codeTable.Count) { ++codeSize; } } if (codeTable.ContainsKey(tableEntry)) { codeStream.WriteBits(BitConverter.GetBytes(codeTable[tableEntry]), 0, codeSize); } else { codeStream.WriteBits(BitConverter.GetBytes(codeTable[CodeTableEntry.MakeColorEntry(indexBuffer.ToArray())]), 0, codeSize); } codeStream.WriteBits(BitConverter.GetBytes(codeTable[CodeTableEntry.EndOfInformation]), 0, codeSize); codeStream.WriteBits(0, (BitNum)(BitNum.MaxValue - codeStream.BitPosition)); var codes = ((MemoryStream)codeStream.UnderlayingStream).ToArray(); GifDataStream.Encode(stream, codes); } }