private static ObjectAnimationUsingKeyFrames GetAnimation(Image imageControl, BitmapSource source)
        {
            var cacheEntry = AnimationCache.Get(source);

            if (cacheEntry == null)
            {
                var decoder = GetDecoder(source, imageControl, out GifFile gifMetadata) as GifBitmapDecoder;
                if (decoder != null && decoder.Frames.Count > 1)
                {
                    var          fullSize      = GetFullSize(decoder, gifMetadata);
                    int          index         = 0;
                    var          keyFrames     = new ObjectKeyFrameCollection();
                    var          totalDuration = TimeSpan.Zero;
                    BitmapSource baseFrame     = null;
                    foreach (var rawFrame in decoder.Frames)
                    {
                        var metadata = GetFrameMetadata(decoder, gifMetadata, index);

                        var frame    = MakeFrame(fullSize, rawFrame, metadata, baseFrame);
                        var keyFrame = new DiscreteObjectKeyFrame(frame, totalDuration);
                        keyFrames.Add(keyFrame);

                        totalDuration += metadata.Delay;

                        switch (metadata.DisposalMethod)
                        {
                        case FrameDisposalMethod.None:
                        case FrameDisposalMethod.DoNotDispose:
                            baseFrame = frame;
                            break;

                        case FrameDisposalMethod.RestoreBackground:
                            if (IsFullFrame(metadata, fullSize))
                            {
                                baseFrame = null;
                            }
                            else
                            {
                                baseFrame = ClearArea(frame, metadata);
                            }
                            break;

                        case FrameDisposalMethod.RestorePrevious:
                            // Reuse same base frame
                            break;
                        }

                        index++;
                    }

                    int repeatCount = GetRepeatCountFromMetadata(decoder, gifMetadata);
                    cacheEntry = new AnimationCacheEntry(keyFrames, totalDuration, repeatCount);
                    AnimationCache.Add(source, cacheEntry);
                }
            }

            if (cacheEntry != null)
            {
                var animation = new ObjectAnimationUsingKeyFrames
                {
                    KeyFrames      = cacheEntry.KeyFrames,
                    Duration       = cacheEntry.Duration,
                    RepeatBehavior = GetActualRepeatBehavior(imageControl, cacheEntry.RepeatCountFromMetadata),
                    SpeedRatio     = GetActualSpeedRatio(imageControl, cacheEntry.Duration)
                };

                AnimationCache.AddControlForSource(source, imageControl);
                return(animation);
            }

            return(null);
        }
        public static void Add(ImageSource source, AnimationCacheEntry entry)
        {
            var key = new CacheKey(source);

            _animationCache[key] = entry;
        }