login

<     >

2017-11-25 10:32:38 (UTC-02:00)

Marcel Rodrigues <marcelgmr@gmail.com>

Add example -- SDL2-based GIF player.

diff --git a/example.c b/example.c
new file mode 100644
index 0000000..b1f23d6
--- /dev/null
+++ b/example.c
@@ -0,0 +1,109 @@
+/* gifdec example -- simple GIF player using SDL2
+ * compiling:
+ *   cc `pkg-config --cflags --libs sdl2` -o example gifdec.c example.c
+ * executing:
+ *   ./example animation.gif
+ * */
+
+#include <stdio.h>
+
+#include <SDL.h>
+
+#include "gifdec.h"
+
+int
+main(int argc, char *argv[])
+{
+    SDL_Window *window;
+    SDL_Renderer *renderer;
+    SDL_Surface *surface;
+    SDL_Texture *texture;
+    SDL_Event event;
+    gd_GIF *gif;
+    char title[32] = {0};
+    Uint8 *color, *frame;
+    void *addr;
+    int i, j;
+    Uint32 pixel;
+    int ret, paused;
+    Uint32 t0, t1;
+
+    if (argc != 2) {
+        fprintf(stderr, "usage:\n  %s gif-file\n", argv[0]);
+        return 1;
+    }
+    gif = gd_open_gif(argv[1]);
+    if (!gif) {
+        fprintf(stderr, "Could not open %s\n", argv[1]);
+        return 1;
+    }
+    frame = malloc(gif->width * gif->height * 3);
+    if (!frame) {
+        fprintf(stderr, "Could not allocate frame\n");
+        return 1;
+    }
+    if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) {
+        SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
+        return 1;
+    }
+    if (SDL_CreateWindowAndRenderer(gif->width, gif->height, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
+        SDL_Log("Couldn't create window and renderer: %s", SDL_GetError());
+        return 1;
+    }
+    snprintf(title, sizeof(title) - 1, "GIF %dx%d %d colors",
+             gif->width, gif->width, gif->palette->size);
+    SDL_SetWindowTitle(window, title);
+    color = &gif->gct.colors[gif->bgindex * 3];
+    SDL_SetRenderDrawColor(renderer, color[0], color[1], color[2], 0x00);
+    SDL_RenderClear(renderer);
+    SDL_RenderPresent(renderer);
+    surface = SDL_CreateRGBSurface(0, gif->width, gif->height, 32, 0, 0, 0, 0);
+    if (!surface) {
+        SDL_Log("SDL_CreateRGBSurface() failed: %s", SDL_GetError());
+        return 1;
+    }
+    paused = 0;
+    while (1) {
+        SDL_PollEvent(&event);
+        if (event.type == SDL_QUIT)
+            break;
+        if (event.type == SDL_KEYDOWN) {
+            if (event.key.keysym.sym == SDLK_q)
+                break;
+            else if (event.key.keysym.sym == SDLK_SPACE)
+                paused = !paused;
+        }
+        if (paused) continue;
+        t0 = SDL_GetTicks();
+        ret = gd_get_frame(gif);
+        if (ret == -1)
+            break;
+        SDL_LockSurface(surface);
+        gd_render_frame(gif, frame);
+        color = frame;
+        for (i = 0; i < gif->height; i++) {
+            for (j = 0; j < gif->width; j++) {
+                addr = surface->pixels + (i * surface->pitch + j * sizeof(pixel));
+                pixel = SDL_MapRGB(surface->format, color[0], color[1], color[2]);
+                memcpy(addr, &pixel, sizeof(pixel));
+                color += 3;
+            }
+        }
+        SDL_UnlockSurface(surface);
+        texture = SDL_CreateTextureFromSurface(renderer, surface);
+        SDL_RenderCopy(renderer, texture, NULL, NULL);
+        SDL_RenderPresent(renderer);
+        SDL_DestroyTexture(texture);
+        t1 = SDL_GetTicks();
+        SDL_Delay(gif->gce.delay * 10 - (t1 - t0));
+        if (ret == 0)
+            gd_rewind(gif);
+    }
+    SDL_FreeSurface(surface);
+    SDL_DestroyRenderer(renderer);
+    SDL_DestroyWindow(window);
+    SDL_Quit();
+    free(frame);
+    gd_close_gif(gif);
+    return 0;
+}