/// <summary> /// Adds next GIF frame. The frame is not written immediately, but is actually deferred /// until the next frame is received so that timing data can be inserted. Invoking /// <code>Finish()</code> flushes all frames. /// </summary> /// <param name="frame">GifFrame containing frame to write.</param> public void AddFrame(GifFrame frame) { if ((frame == null)) throw new ArgumentNullException("Can't add a null frame to the gif."); if (!m_HasStarted) throw new InvalidOperationException("Call Start() before adding frames to the gif."); // Use first frame's size if (!m_IsSizeSet) SetSize(frame.Width, frame.Height); m_CurrentFrame = frame; GetImagePixels(); AnalyzePixels(); if (m_IsFirstFrame) { WriteLSD(); WritePalette(); if (m_Repeat >= 0) WriteNetscapeExt(); } WriteGraphicCtrlExt(); WriteImageDesc(); if (!m_IsFirstFrame) WritePalette(); WritePixels(); m_IsFirstFrame = false; }
/// <summary> /// Flushes any pending data and closes output file. /// If writing to an OutputStream, the stream is not closed. /// </summary> public void Finish() { if (!m_HasStarted) throw new InvalidOperationException("Can't finish a non-started gif."); m_HasStarted = false; try { m_FileStream.WriteByte(0x3b); // Gif trailer m_FileStream.Flush(); if (m_ShouldCloseStream) m_FileStream.Close(); } catch (IOException e) { throw e; } // Reset for subsequent use m_FileStream = null; m_CurrentFrame = null; m_Pixels = null; m_IndexedPixels = null; m_ColorTab = null; m_ShouldCloseStream = false; m_IsFirstFrame = true; }