# New block - ciAnimatedGif

**URL:** https://discourse.libcinder.org/t/new-block-cianimatedgif/301
**Category:** CinderBlocks
**Created:** [October 3, 2016, 3:59pm UTC](https://discourse.libcinder.org/t/new-block-cianimatedgif/301 "2016-10-03T15:59:26Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![sharkbox](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/sharkbox/32/39_2.png) [@sharkbox](https://discourse.libcinder.org/u/sharkbox)
#### Post date: [October 3, 2016, 3:59pm UTC](https://discourse.libcinder.org/t/new-block-cianimatedgif/301/1 "2016-10-03T15:59:26Z")

</div>

Hey amigos. Here is a quick block for a more advanced playback of animated gifs. It takes into account that framerates can be different between every single frame, and also exposes global palettes often included in gifs. While I don’t recommend using a lot of gifs in your project, it’s something that gets requested enough from clients that I finally made this so I could stop worrying about it. Use is super simple.

```
ciAnimatedGifRef mGif = ciAnimatedGif::create( loadAsset("someGif.gif") );
mGif->draw();

```

Find the block here: [https://github.com/cwhitney/ciAnimatedGif](https://github.com/cwhitney/ciAnimatedGif)  
It’s based on the information in this article: [http://giflib.sourceforge.net/whatsinagif/bits\_and\_bytes.html](http://giflib.sourceforge.net/whatsinagif/bits_and_bytes.html)

Now - a question! When I load the gif frames, I am storing them as a vector of Surfaces. When they get displayed, I convert it to a texture right before it displays, which means an upload to the gpu. The alternative is to upload every frame to the gpu at the beginning, and just leave them there with gl::TextureRefs. I did it this way because if you’re displaying gifs, then you might be displaying a lot of them, and I didn’t want to clog the gpu, especially if you’re not displaying them. How would you handle this?

-c

---

<div class="post-metadata">

### Author: ![eight\_io](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/eight_io/32/57_2.png) [@eight\_io](https://discourse.libcinder.org/u/eight_io)
#### Post date: [October 3, 2016, 6:11pm UTC](https://discourse.libcinder.org/t/new-block-cianimatedgif/301/2 "2016-10-03T18:11:52Z")

</div>

@sharkbox –– Thanks! Works on iOS too.

–8

---

<div class="post-metadata">

### Author: ![sharkbox](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/sharkbox/32/39_2.png) [@sharkbox](https://discourse.libcinder.org/u/sharkbox)
#### Post date: [October 3, 2016, 6:13pm UTC](https://discourse.libcinder.org/t/new-block-cianimatedgif/301/3 "2016-10-03T18:13:18Z")

</div>

Amazing, thanks for checking!

---

<div class="post-metadata">

### Author: ![rich.e](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/rich.e/32/1025_2.png) [@rich.e](https://discourse.libcinder.org/u/rich.e)
#### Post date: [October 3, 2016, 7:01pm UTC](https://discourse.libcinder.org/t/new-block-cianimatedgif/301/4 "2016-10-03T19:01:54Z")

</div>

Definitely handy when it comes up, thanks for sharing it.

> Now - a question! When I load the gif frames, I am storing them as a vector of Surfaces. When they get displayed, I convert it to a texture right before it displays, which means an upload to the gpu. The alternative is to upload every frame to the gpu at the beginning, and just leave them there with gl::TextureRefs. I did it this way because if you’re displaying gifs, then you might be displaying a lot of them, and I didn’t want to clog the gpu, especially if you’re not displaying them. How would you handle this?

What about making most of that a virtual `AnimatedGifBase`, then you can make two more concrete subclasses: `AnimatedGif` that stores the data as `Surface`’s and another `AnimatedGifGl` that stores them as `gl::Texture`s all on the gpu. I know that at least for me, I’d almost always use the gl version, especially if I’m using a card with like 4+ gigs of VRAM. Also, I think it would be nice if you could return the current frame to be drawn, and let the user draw it however they like. Could be in addition to the `draw()` methods if you find that more convenient.

cheers,  
Rich

---

<div class="post-metadata">

### Author: ![sharkbox](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/sharkbox/32/39_2.png) [@sharkbox](https://discourse.libcinder.org/u/sharkbox)
#### Post date: [October 3, 2016, 7:20pm UTC](https://discourse.libcinder.org/t/new-block-cianimatedgif/301/5 "2016-10-03T19:20:29Z")

</div>

Good advice Rich. I might just make ciAnimatedGif use textures as a default and provide ciAnimatedGifSurf as well.

---

<div class="post-metadata">

### Author: ![num3ric](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/num3ric/32/7_2.png) [@num3ric](https://discourse.libcinder.org/u/num3ric)
#### Post date: [October 4, 2016, 6:48pm UTC](https://discourse.libcinder.org/t/new-block-cianimatedgif/301/6 "2016-10-04T18:48:34Z")

</div>

For the gl version, using a GL\_TEXTURE\_2D\_ARRAY over a vector of gl::Texture2d would be significantly more optimal in the scenario where you want +1000 gifs all scrubbing at a different frame, which we may want 🙂 Though it implies a custom playback shader, and not sure it would work on mobile platforms? You could argue for or against it.

> <https://github.com/cinder/Cinder/blob/master/include/cinder/gl/Texture.h#L645>

I did so with image sequences, but had to fix an issue with mimaps. You might have the same problem.  
[https://github.com/cinder/Cinder/pull/1432](https://github.com/cinder/Cinder/pull/1432)
