97 lines
2.7 KiB
C#
97 lines
2.7 KiB
C#
using System;
|
|
using HandyControl.Controls;
|
|
|
|
namespace HandyControl.Data
|
|
{
|
|
public class GifImageInfo
|
|
{
|
|
private const int PropertyTagFrameDelay = 0x5100;
|
|
|
|
private int _frame;
|
|
|
|
private readonly int[] _frameDelay;
|
|
|
|
public int FrameCount { get; }
|
|
|
|
internal GifImage Image { get; }
|
|
|
|
public bool Animated { get; }
|
|
|
|
public EventHandler FrameChangedHandler { get; set; }
|
|
|
|
internal int FrameTimer { get; set; }
|
|
|
|
public bool FrameDirty { get; private set; }
|
|
|
|
public int Frame
|
|
{
|
|
get => _frame;
|
|
set
|
|
{
|
|
if (_frame != value)
|
|
{
|
|
if (value < 0 || value >= FrameCount)
|
|
{
|
|
throw new ArgumentException("InvalidFrame");
|
|
}
|
|
|
|
if (Animated)
|
|
{
|
|
_frame = value;
|
|
FrameDirty = true;
|
|
|
|
OnFrameChanged(EventArgs.Empty);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public GifImageInfo(GifImage image)
|
|
{
|
|
Image = image;
|
|
Animated = ImageAnimator.CanAnimate(image);
|
|
|
|
if (Animated)
|
|
{
|
|
FrameCount = image.GetFrameCount(GifFrameDimension.Time);
|
|
|
|
var frameDelayItem = image.GetPropertyItem(PropertyTagFrameDelay);
|
|
|
|
// If the image does not have a frame delay, we just return 0.
|
|
//
|
|
if (frameDelayItem != null)
|
|
{
|
|
// Convert the frame delay from byte[] to int
|
|
//
|
|
var values = frameDelayItem.Value;
|
|
_frameDelay = new int[FrameCount];
|
|
for (int i = 0; i < FrameCount; ++i)
|
|
{
|
|
_frameDelay[i] = values[i * 4] + 256 * values[i * 4 + 1] + 256 * 256 * values[i * 4 + 2] + 256 * 256 * 256 * values[i * 4 + 3];
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FrameCount = 1;
|
|
}
|
|
if (_frameDelay == null)
|
|
{
|
|
_frameDelay = new int[FrameCount];
|
|
}
|
|
}
|
|
|
|
public int FrameDelay(int frame) => _frameDelay[frame];
|
|
|
|
internal void UpdateFrame()
|
|
{
|
|
if (FrameDirty)
|
|
{
|
|
Image.SelectActiveFrame(GifFrameDimension.Time, Frame);
|
|
FrameDirty = false;
|
|
}
|
|
}
|
|
|
|
protected void OnFrameChanged(EventArgs e) => FrameChangedHandler?.Invoke(Image, e);
|
|
}
|
|
} |