/// <summary> /// Reads the graphic control extension. /// </summary> private void ReadGraphicalControlExtension() { byte[] buffer = new byte[6]; this.currentStream.Read(buffer, 0, buffer.Length); byte packed = buffer[1]; this.graphicsControlExtension = new GifGraphicsControlExtension { DelayTime = BitConverter.ToInt16(buffer, 2), TransparencyIndex = buffer[4], TransparencyFlag = (packed & 0x01) == 1, DisposalMethod = (DisposalMethod)((packed & 0x1C) >> 2) }; }
/// <summary> /// Writes the graphics control extension to the stream. /// </summary> /// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <param name="image">The <see cref="ImageBase{T,TP}"/> to encode.</param> /// <param name="writer">The stream to write to.</param> /// <param name="transparencyIndex">The index of the color in the color palette to make transparent.</param> private void WriteGraphicalControlExtension <T, TP>(ImageBase <T, TP> image, EndianBinaryWriter writer, int transparencyIndex) where T : IPackedVector <TP> where TP : struct { // TODO: Check transparency logic. bool hasTransparent = transparencyIndex > -1; DisposalMethod disposalMethod = hasTransparent ? DisposalMethod.RestoreToBackground : DisposalMethod.Unspecified; GifGraphicsControlExtension extension = new GifGraphicsControlExtension() { DisposalMethod = disposalMethod, TransparencyFlag = hasTransparent, TransparencyIndex = transparencyIndex, DelayTime = image.FrameDelay }; // Reduce the number of writes. byte[] intro = { GifConstants.ExtensionIntroducer, GifConstants.GraphicControlLabel, 4 // Size }; writer.Write(intro); PackedField field = new PackedField(); field.SetBits(3, 3, (int)extension.DisposalMethod); // 1-3 : Reserved, 4-6 : Disposal // TODO: Allow this as an option. field.SetBit(6, false); // 7 : User input - 0 = none field.SetBit(7, extension.TransparencyFlag); // 8: Has transparent. writer.Write(field.Byte); writer.Write((ushort)extension.DelayTime); writer.Write((byte)(extension.TransparencyIndex == -1 ? 255 : extension.TransparencyIndex)); writer.Write(GifConstants.Terminator); }
/// <summary> /// Writes the graphics control extension to the stream. /// </summary> /// <param name="image">The <see cref="ImageBase"/> to encode.</param> /// <param name="stream">The stream to write to.</param> private void WriteGraphicalControlExtension(ImageBase image, Stream stream) { // Calculate the quality. int quality = this.Quality > 0 ? this.Quality : image.Quality; quality = quality > 0 ? quality.Clamp(1, 256) : 256; // TODO: Check transparency logic. bool hasTransparent = quality > 1; DisposalMethod disposalMethod = hasTransparent ? DisposalMethod.RestoreToBackground : DisposalMethod.Unspecified; GifGraphicsControlExtension extension = new GifGraphicsControlExtension() { DisposalMethod = disposalMethod, TransparencyFlag = hasTransparent, TransparencyIndex = quality - 1, // Quantizer sets last index as transparent. DelayTime = image.FrameDelay }; this.WriteByte(stream, GifConstants.ExtensionIntroducer); this.WriteByte(stream, GifConstants.GraphicControlLabel); this.WriteByte(stream, 4); // Size int packed = 0 | // 1-3 : Reserved (int)extension.DisposalMethod << 2 | // 4-6 : Disposal 0 | // 7 : User input - 0 = none (extension.TransparencyFlag ? 1 : 0); // 8: Has transparent. this.WriteByte(stream, packed); this.WriteShort(stream, extension.DelayTime); this.WriteByte(stream, extension.TransparencyIndex); this.WriteByte(stream, GifConstants.Terminator); }