internal static void EnsureSave(GifImage image, string filename, Stream dataStream) { if (!image.RawGuid.Equals(GifGuid)) { return; } var animatedGif = false; var dimensions = image.FrameDimensionsList; if (dimensions.Select(guid => new GifFrameDimension(guid)).Contains(GifFrameDimension.Time)) { animatedGif = image.GetFrameCount(GifFrameDimension.Time) > 1; } if (!animatedGif) { return; } try { Stream created = null; long lastPos = 0; if (dataStream != null) { lastPos = dataStream.Position; dataStream.Position = 0; } try { if (dataStream == null) { created = dataStream = File.OpenRead(filename); } image._rawData = new byte[(int)dataStream.Length]; dataStream.Read(image._rawData, 0, (int)dataStream.Length); } finally { if (created != null) { created.Close(); } else { // ReSharper disable once PossibleNullReferenceException dataStream.Position = lastPos; } } } // possible exceptions for reading the filename catch (UnauthorizedAccessException) { } catch (DirectoryNotFoundException) { } catch (IOException) { } // possible exceptions for setting/getting the position inside dataStream catch (NotSupportedException) { } catch (ObjectDisposedException) { } // possible exception when reading stuff into dataStream catch (ArgumentException) { } }
public static void Animate(GifImage image, EventHandler onFrameChangedHandler) { if (image == null) { return; } GifImageInfo imageInfo; // See comment in the class header about locking the image ref. lock (image) { // could we avoid creating an ImageInfo object if FrameCount == 1 ? imageInfo = new GifImageInfo(image); } // If the image is already animating, stop animating it StopAnimate(image, onFrameChangedHandler); // Acquire a writer lock to modify the image info list. If the thread has a reader lock we need to upgrade // it to a writer lock; acquiring a reader lock in this case would block the thread on itself. // If the thread already has a writer lock its ref count will be incremented w/o placing the request in the // writer queue. See ReaderWriterLock.AcquireWriterLock method in the MSDN. var readerLockHeld = RwImgListLock.IsReaderLockHeld; var lockDowngradeCookie = new LockCookie(); ThreadWriterLockWaitCount++; try { if (readerLockHeld) { lockDowngradeCookie = RwImgListLock.UpgradeToWriterLock(Timeout.Infinite); } else { RwImgListLock.AcquireWriterLock(Timeout.Infinite); } } finally { ThreadWriterLockWaitCount--; } try { if (imageInfo.Animated) { // Construct the image array // if (ImageInfoList == null) { ImageInfoList = new List <GifImageInfo>(); } // Add the new image // imageInfo.FrameChangedHandler = onFrameChangedHandler; ImageInfoList.Add(imageInfo); // Construct a new timer thread if we haven't already // if (AnimationThread == null) { AnimationThread = new Thread(AnimateImages50Ms) { Name = typeof(ImageAnimator).Name, IsBackground = true }; AnimationThread.Start(); } } } finally { if (readerLockHeld) { RwImgListLock.DowngradeFromWriterLock(ref lockDowngradeCookie); } else { RwImgListLock.ReleaseWriterLock(); } } }