/// <summary> /// Writes the logical screen descriptor to the stream. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="image">The image to encode.</param> /// <param name="writer">The writer to write to the stream with.</param> /// <param name="tranparencyIndex">The transparency index to set the default background index to.</param> private void WriteLogicalScreenDescriptor <TPixel>(Image <TPixel> image, EndianBinaryWriter writer, int tranparencyIndex) where TPixel : struct, IPixel <TPixel> { GifLogicalScreenDescriptor descriptor = new GifLogicalScreenDescriptor { Width = (short)image.Width, Height = (short)image.Height, GlobalColorTableFlag = false, // Always false for now. GlobalColorTableSize = this.bitDepth - 1, BackgroundColorIndex = (byte)tranparencyIndex }; writer.Write((ushort)descriptor.Width); writer.Write((ushort)descriptor.Height); PackedField field = default(PackedField); field.SetBit(0, descriptor.GlobalColorTableFlag); // 1 : Global color table flag = 1 || 0 (GCT used/ not used) field.SetBits(1, 3, descriptor.GlobalColorTableSize); // 2-4 : color resolution field.SetBit(4, false); // 5 : GCT sort flag = 0 field.SetBits(5, 3, descriptor.GlobalColorTableSize); // 6-8 : GCT size. 2^(N+1) // Reduce the number of writes this.buffer[0] = field.Byte; this.buffer[1] = descriptor.BackgroundColorIndex; // Background Color Index this.buffer[2] = descriptor.PixelAspectRatio; // Pixel aspect ratio. Assume 1:1 writer.Write(this.buffer, 0, 3); }
/// <summary> /// Writes the graphics control extension to the stream. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="image">The <see cref="ImageBase{TPixel}"/> to encode.</param> /// <param name="metaData">The metadata of the image or frame.</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 <TPixel>(ImageBase <TPixel> image, IMetaData metaData, EndianBinaryWriter writer, int transparencyIndex) where TPixel : struct, IPixel <TPixel> { GifGraphicsControlExtension extension = new GifGraphicsControlExtension() { DisposalMethod = metaData.DisposalMethod, TransparencyFlag = transparencyIndex < 255, TransparencyIndex = transparencyIndex, DelayTime = metaData.FrameDelay }; // Write the intro. this.buffer[0] = GifConstants.ExtensionIntroducer; this.buffer[1] = GifConstants.GraphicControlLabel; this.buffer[2] = 4; writer.Write(this.buffer, 0, 3); PackedField field = default(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); writer.Write(GifConstants.Terminator); }
/// <summary> /// Writes the logical screen descriptor to the stream. /// </summary> /// <typeparam name="TColor">The pixel format.</typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam> /// <param name="image">The image to encode.</param> /// <param name="writer">The writer to write to the stream with.</param> /// <param name="tranparencyIndex">The transparency index to set the default background index to.</param> private void WriteLogicalScreenDescriptor <TColor, TPacked>(Image <TColor, TPacked> image, EndianBinaryWriter writer, int tranparencyIndex) where TColor : struct, IPackedPixel <TPacked> where TPacked : struct, IEquatable <TPacked> { GifLogicalScreenDescriptor descriptor = new GifLogicalScreenDescriptor { Width = (short)image.Width, Height = (short)image.Height, GlobalColorTableFlag = false, // Always false for now. GlobalColorTableSize = this.bitDepth - 1, BackgroundColorIndex = (byte)(tranparencyIndex > -1 ? tranparencyIndex : 255) }; writer.Write((ushort)descriptor.Width); writer.Write((ushort)descriptor.Height); PackedField field = default(PackedField); field.SetBit(0, descriptor.GlobalColorTableFlag); // 1 : Global color table flag = 1 || 0 (GCT used/ not used) field.SetBits(1, 3, descriptor.GlobalColorTableSize); // 2-4 : color resolution field.SetBit(4, false); // 5 : GCT sort flag = 0 field.SetBits(5, 3, descriptor.GlobalColorTableSize); // 6-8 : GCT size. 2^(N+1) // Reduce the number of writes byte[] arr = { field.Byte, descriptor.BackgroundColorIndex, // Background Color Index descriptor.PixelAspectRatio // Pixel aspect ratio. Assume 1:1 }; writer.Write(arr); }
/// <summary> /// Writes the image descriptor to the stream. /// </summary> /// <typeparam name="TColor">The pixel format.</typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam> /// <param name="image">The <see cref="ImageBase{TColor, TPacked}"/> to be encoded.</param> /// <param name="writer">The stream to write to.</param> private void WriteImageDescriptor <TColor, TPacked>(ImageBase <TColor, TPacked> image, EndianBinaryWriter writer) where TColor : struct, IPackedPixel <TPacked> where TPacked : struct, IEquatable <TPacked> { writer.Write(GifConstants.ImageDescriptorLabel); // 2c // TODO: Can we capture this? writer.Write((ushort)0); // Left position writer.Write((ushort)0); // Top position writer.Write((ushort)image.Width); writer.Write((ushort)image.Height); PackedField field = default(PackedField); field.SetBit(0, true); // 1: Local color table flag = 1 (LCT used) field.SetBit(1, false); // 2: Interlace flag 0 field.SetBit(2, false); // 3: Sort flag 0 field.SetBits(5, 3, this.bitDepth - 1); // 4-5: Reserved, 6-8 : LCT size. 2^(N+1) writer.Write(field.Byte); }
/// <summary> /// Writes the graphics control extension to the stream. /// </summary> /// <typeparam name="TColor">The pixel format.</typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam> /// <param name="image">The <see cref="ImageBase{TColor, TPacked}"/> 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 <TColor, TPacked>(ImageBase <TColor, TPacked> image, EndianBinaryWriter writer, int transparencyIndex) where TColor : struct, IPackedPixel <TPacked> where TPacked : 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 = default(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> /// <typeparam name="TColor">The pixel format.</typeparam> /// <param name="image">The <see cref="ImageBase{TColor}"/> to encode.</param> /// <param name="metaData">The metadata of the image or frame.</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 <TColor>(ImageBase <TColor> image, IMetaData metaData, EndianBinaryWriter writer, int transparencyIndex) where TColor : struct, IPackedPixel, IEquatable <TColor> { // TODO: Check transparency logic. bool hasTransparent = transparencyIndex < 255; DisposalMethod disposalMethod = hasTransparent ? DisposalMethod.RestoreToBackground : DisposalMethod.Unspecified; GifGraphicsControlExtension extension = new GifGraphicsControlExtension() { DisposalMethod = disposalMethod, TransparencyFlag = hasTransparent, TransparencyIndex = transparencyIndex, DelayTime = metaData.FrameDelay }; // Write the intro. this.buffer[0] = GifConstants.ExtensionIntroducer; this.buffer[1] = GifConstants.GraphicControlLabel; this.buffer[2] = 4; writer.Write(this.buffer, 0, 3); PackedField field = default(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); writer.Write(GifConstants.Terminator); }