Browse Source

Ensure correct disposal method is carried across

af/merge-core
James Jackson-South 9 years ago
parent
commit
de2e51e224
  1. 18
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  2. 12
      src/ImageSharp/Formats/Gif/GifEncoderCore.cs
  3. 11
      src/ImageSharp/MetaData/IMetaData.cs
  4. 13
      src/ImageSharp/MetaData/ImageFrameMetaData.cs
  5. 20
      src/ImageSharp/MetaData/ImageMetaData.cs

18
src/ImageSharp/Formats/Gif/GifDecoderCore.cs

@ -8,6 +8,7 @@ namespace ImageSharp.Formats
using System; using System;
using System.Buffers; using System.Buffers;
using System.IO; using System.IO;
using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
@ -332,6 +333,7 @@ namespace ImageSharp.Formats
/// </summary> /// </summary>
/// <param name="imageDescriptor">The <see cref="GifImageDescriptor"/>.</param> /// <param name="imageDescriptor">The <see cref="GifImageDescriptor"/>.</param>
/// <param name="indices">The pixel array to write to.</param> /// <param name="indices">The pixel array to write to.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ReadFrameIndices(GifImageDescriptor imageDescriptor, byte[] indices) private void ReadFrameIndices(GifImageDescriptor imageDescriptor, byte[] indices)
{ {
int dataSize = this.currentStream.ReadByte(); int dataSize = this.currentStream.ReadByte();
@ -366,7 +368,7 @@ namespace ImageSharp.Formats
// This initializes the image to become fully transparent because the alpha channel is zero. // This initializes the image to become fully transparent because the alpha channel is zero.
this.image = Image.Create<TPixel>(imageWidth, imageHeight, this.metaData, this.configuration); this.image = Image.Create<TPixel>(imageWidth, imageHeight, this.metaData, this.configuration);
this.SetFrameDelay(this.metaData); this.SetFrameMetaData(this.metaData);
image = this.image; image = this.image;
} }
@ -380,7 +382,7 @@ namespace ImageSharp.Formats
currentFrame = this.previousFrame.Clone(); currentFrame = this.previousFrame.Clone();
this.SetFrameDelay(currentFrame.MetaData); this.SetFrameMetaData(currentFrame.MetaData);
image = currentFrame; image = currentFrame;
@ -506,14 +508,20 @@ namespace ImageSharp.Formats
} }
/// <summary> /// <summary>
/// Sets the frame delay in the metadata. /// Sets the frames metadata.
/// </summary> /// </summary>
/// <param name="metaData">The meta data.</param> /// <param name="metaData">The meta data.</param>
private void SetFrameDelay(IMetaData metaData) [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SetFrameMetaData(IMetaData metaData)
{ {
if (this.graphicsControlExtension != null && this.graphicsControlExtension.DelayTime > 0) if (this.graphicsControlExtension != null && this.graphicsControlExtension.DelayTime > 0)
{ {
metaData.FrameDelay = this.graphicsControlExtension.DelayTime; if (this.graphicsControlExtension.DelayTime > 0)
{
metaData.FrameDelay = this.graphicsControlExtension.DelayTime;
}
metaData.DisposalMethod = this.graphicsControlExtension.DisposalMethod;
} }
} }
} }

12
src/ImageSharp/Formats/Gif/GifEncoderCore.cs

@ -191,7 +191,7 @@ namespace ImageSharp.Formats
{ {
Width = (short)image.Width, Width = (short)image.Width,
Height = (short)image.Height, Height = (short)image.Height,
GlobalColorTableFlag = false, // Always false for now. GlobalColorTableFlag = false, // TODO: Always false for now.
GlobalColorTableSize = this.bitDepth - 1, GlobalColorTableSize = this.bitDepth - 1,
BackgroundColorIndex = (byte)tranparencyIndex BackgroundColorIndex = (byte)tranparencyIndex
}; };
@ -312,16 +312,10 @@ namespace ImageSharp.Formats
private void WriteGraphicalControlExtension<TPixel>(ImageBase<TPixel> image, IMetaData metaData, EndianBinaryWriter writer, int transparencyIndex) private void WriteGraphicalControlExtension<TPixel>(ImageBase<TPixel> image, IMetaData metaData, EndianBinaryWriter writer, int transparencyIndex)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
// TODO: Check transparency logic.
bool hasTransparent = transparencyIndex < 255;
DisposalMethod disposalMethod = hasTransparent
? DisposalMethod.RestoreToBackground
: DisposalMethod.Unspecified;
GifGraphicsControlExtension extension = new GifGraphicsControlExtension() GifGraphicsControlExtension extension = new GifGraphicsControlExtension()
{ {
DisposalMethod = disposalMethod, DisposalMethod = metaData.DisposalMethod,
TransparencyFlag = hasTransparent, TransparencyFlag = transparencyIndex < 255,
TransparencyIndex = transparencyIndex, TransparencyIndex = transparencyIndex,
DelayTime = metaData.FrameDelay DelayTime = metaData.FrameDelay
}; };

11
src/ImageSharp/MetaData/IMetaData.cs

@ -5,6 +5,8 @@
namespace ImageSharp namespace ImageSharp
{ {
using ImageSharp.Formats;
/// <summary> /// <summary>
/// Encapsulates the metadata of an image frame. /// Encapsulates the metadata of an image frame.
/// </summary> /// </summary>
@ -12,10 +14,17 @@ namespace ImageSharp
{ {
/// <summary> /// <summary>
/// Gets or sets the frame delay for animated images. /// Gets or sets the frame delay for animated images.
/// If not 0, this field specifies the number of hundredths (1/100) of a second to /// If not 0, when utilized in Gif animation, this field specifies the number of hundredths (1/100) of a second to
/// wait before continuing with the processing of the Data Stream. /// wait before continuing with the processing of the Data Stream.
/// The clock starts ticking immediately after the graphic is rendered. /// The clock starts ticking immediately after the graphic is rendered.
/// </summary> /// </summary>
int FrameDelay { get; set; } int FrameDelay { get; set; }
/// <summary>
/// Gets or sets the disposal method for animated images.
/// Primarily used in Gif animation, this field indicates the way in which the graphic is to
/// be treated after being displayed.
/// </summary>
DisposalMethod DisposalMethod { get; set; }
} }
} }

13
src/ImageSharp/MetaData/ImageFrameMetaData.cs

@ -5,6 +5,8 @@
namespace ImageSharp namespace ImageSharp
{ {
using ImageSharp.Formats;
/// <summary> /// <summary>
/// Encapsulates the metadata of an image frame. /// Encapsulates the metadata of an image frame.
/// </summary> /// </summary>
@ -29,14 +31,13 @@ namespace ImageSharp
DebugGuard.NotNull(other, nameof(other)); DebugGuard.NotNull(other, nameof(other));
this.FrameDelay = other.FrameDelay; this.FrameDelay = other.FrameDelay;
this.DisposalMethod = other.DisposalMethod;
} }
/// <summary> /// <inheritdoc/>
/// Gets or sets the frame delay for animated images.
/// If not 0, this field specifies the number of hundredths (1/100) of a second to
/// wait before continuing with the processing of the Data Stream.
/// The clock starts ticking immediately after the graphic is rendered.
/// </summary>
public int FrameDelay { get; set; } public int FrameDelay { get; set; }
/// <inheritdoc/>
public DisposalMethod DisposalMethod { get; set; }
} }
} }

20
src/ImageSharp/MetaData/ImageMetaData.cs

@ -7,6 +7,7 @@ namespace ImageSharp
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using ImageSharp.Formats;
/// <summary> /// <summary>
/// Encapsulates the metadata of an image. /// Encapsulates the metadata of an image.
@ -52,6 +53,7 @@ namespace ImageSharp
this.VerticalResolution = other.VerticalResolution; this.VerticalResolution = other.VerticalResolution;
this.Quality = other.Quality; this.Quality = other.Quality;
this.FrameDelay = other.FrameDelay; this.FrameDelay = other.FrameDelay;
this.DisposalMethod = other.DisposalMethod;
this.RepeatCount = other.RepeatCount; this.RepeatCount = other.RepeatCount;
foreach (ImageProperty property in other.Properties) foreach (ImageProperty property in other.Properties)
@ -83,10 +85,10 @@ namespace ImageSharp
set set
{ {
if (value > 0) if (value > 0)
{ {
this.horizontalResolution = value; this.horizontalResolution = value;
} }
} }
} }
@ -116,14 +118,12 @@ namespace ImageSharp
/// </summary> /// </summary>
public ExifProfile ExifProfile { get; set; } public ExifProfile ExifProfile { get; set; }
/// <summary> /// <inheritdoc/>
/// Gets or sets the frame delay for animated images.
/// If not 0, this field specifies the number of hundredths (1/100) of a second to
/// wait before continuing with the processing of the Data Stream.
/// The clock starts ticking immediately after the graphic is rendered.
/// </summary>
public int FrameDelay { get; set; } public int FrameDelay { get; set; }
/// <inheritdoc/>
public DisposalMethod DisposalMethod { get; set; }
/// <summary> /// <summary>
/// Gets the list of properties for storing meta information about this image. /// Gets the list of properties for storing meta information about this image.
/// </summary> /// </summary>

Loading…
Cancel
Save