internal static async Task <GifDataStream> ReadAsync(Stream stream) { var file = new GifDataStream(); await file.ReadInternalAsync(stream).ConfigureAwait(false); return(file); }
private Animator(Stream sourceStream, Uri sourceUri, GifDataStream metadata, RepeatBehavior repeatBehavior, Image image) { _sourceStream = sourceStream; _sourceUri = sourceUri; _metadata = metadata; _image = image; _palettes = CreatePalettes(metadata); _bitmap = CreateBitmap(metadata); var desc = metadata.Header.LogicalScreenDescriptor; _stride = 4 * ((desc.Width * 32 + 31) / 32); _previousBackBuffer = new byte[desc.Height * _stride]; _indexStreamBuffer = CreateIndexStreamBuffer(metadata, _sourceStream); _timingManager = CreateTimingManager(metadata, repeatBehavior); }
private static RepeatBehavior GetRepeatBehavior(GifDataStream metadata) { if (metadata.RepeatCount == 0) return RepeatBehavior.Forever; return new RepeatBehavior(metadata.RepeatCount); }
private static byte[] CreateIndexStreamBuffer(GifDataStream metadata, Stream stream) { // Find the size of the largest frame pixel data // (ignoring the fact that we include the next frame's header) long lastSize = stream.Length - metadata.Frames.Last().ImageData.CompressedDataStartOffset; long maxSize = lastSize; if (metadata.Frames.Count > 1) { var sizes = metadata.Frames.Zip(metadata.Frames.Skip(1), (f1, f2) => f2.ImageData.CompressedDataStartOffset - f1.ImageData.CompressedDataStartOffset); maxSize = Math.Max(sizes.Max(), lastSize); } // Need 4 extra bytes so that BitReader doesn't need to check the size for every read return new byte[maxSize + 4]; }
private static Dictionary<int, GifPalette> CreatePalettes(GifDataStream metadata) { var palettes = new Dictionary<int, GifPalette>(); Color[] globalColorTable = null; if (metadata.Header.LogicalScreenDescriptor.HasGlobalColorTable) { globalColorTable = metadata.GlobalColorTable .Select(gc => Color.FromArgb(0xFF, gc.R, gc.G, gc.B)) .ToArray(); } for (int i = 0; i < metadata.Frames.Count; i++) { var frame = metadata.Frames[i]; var colorTable = globalColorTable; if (frame.Descriptor.HasLocalColorTable) { colorTable = frame.LocalColorTable .Select(gc => Color.FromArgb(0xFF, gc.R, gc.G, gc.B)) .ToArray(); } int? transparencyIndex = null; var gce = frame.GraphicControl; if (gce != null && gce.HasTransparency) { transparencyIndex = gce.TransparencyIndex; } palettes[i] = new GifPalette(transparencyIndex, colorTable); } return palettes; }
private static WriteableBitmap CreateBitmap(GifDataStream metadata) { var desc = metadata.Header.LogicalScreenDescriptor; #if WPF var bitmap = new WriteableBitmap(desc.Width, desc.Height, 96, 96, PixelFormats.Bgra32, null); #elif WINRT var bitmap = new WriteableBitmap(desc.Width, desc.Height); #else #error Not implemented #endif return bitmap; }
private TimingManager CreateTimingManager(GifDataStream metadata, RepeatBehavior repeatBehavior) { var actualRepeatBehavior = repeatBehavior == default(RepeatBehavior) ? GetRepeatBehavior(metadata) : repeatBehavior; var manager = new TimingManager(actualRepeatBehavior); foreach (var frame in metadata.Frames) { manager.Add(GetFrameDelay(frame)); } manager.Completed += TimingManagerCompleted; return manager; }
public ImageAnimator(Stream sourceStream, Uri sourceUri, GifDataStream metadata, RepeatBehavior repeatBehavior, Image image) : base(sourceStream, sourceUri, metadata, repeatBehavior) { ErrorSource = image; }
private BrushAnimator(Stream sourceStream, Uri sourceUri, GifDataStream metadata, RepeatBehavior repeatBehavior) : base(sourceStream, sourceUri, metadata, repeatBehavior) { Brush = new ImageBrush {ImageSource = Bitmap}; }
internal static async Task<GifDataStream> ReadAsync(Stream stream) { var file = new GifDataStream(); await file.ReadInternalAsync(stream).ConfigureAwait(false); return file; }
public ImageAnimator(Stream sourceStream, Uri sourceUri, GifDataStream metadata, RepeatBehavior repeatBehavior, Image image) : base(sourceStream, sourceUri, metadata, repeatBehavior) { _image = image; OnRepeatBehaviorChanged(); // in case the value has changed during creation }