Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2008 Sean Fox <dyntryx@gmail.com>
  3.  * Copyright 2008 James Bursa <james@netsurf-browser.org>
  4.  *
  5.  * This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/
  6.  * Licenced under the MIT License,
  7.  *                http://www.opensource.org/licenses/mit-license.php
  8.  */
  9.  
  10. #include <assert.h>
  11. #include <errno.h>
  12. #include <stdbool.h>
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <sys/stat.h>
  17. #include "../libnsgif.h"
  18.  
  19. unsigned char *load_file(const char *path, size_t *data_size);
  20. void warning(const char *context, int code);
  21. void *bitmap_create(int width, int height);
  22. void bitmap_set_opaque(void *bitmap, bool opaque);
  23. bool bitmap_test_opaque(void *bitmap);
  24. unsigned char *bitmap_get_buffer(void *bitmap);
  25. void bitmap_destroy(void *bitmap);
  26. void bitmap_modified(void *bitmap);
  27.  
  28.  
  29. int main(int argc, char *argv[])
  30. {
  31.         gif_bitmap_callback_vt bitmap_callbacks = {
  32.                 bitmap_create,
  33.                 bitmap_destroy,
  34.                 bitmap_get_buffer,
  35.                 bitmap_set_opaque,
  36.                 bitmap_test_opaque,
  37.                 bitmap_modified
  38.         };
  39.         gif_animation gif;
  40.         size_t size;
  41.         gif_result code;
  42.         unsigned int i;
  43.  
  44.         if (argc != 2) {
  45.                 fprintf(stderr, "Usage: %s image.gif\n", argv[0]);
  46.                 return 1;
  47.         }
  48.  
  49.         /* create our gif animation */
  50.         gif_create(&gif, &bitmap_callbacks);
  51.  
  52.         /* load file into memory */
  53.         unsigned char *data = load_file(argv[1], &size);
  54.  
  55.         /* begin decoding */
  56.         do {
  57.                 code = gif_initialise(&gif, size, data);
  58.                 if (code != GIF_OK && code != GIF_WORKING) {
  59.                         warning("gif_initialise", code);
  60.                         exit(1);
  61.                 }
  62.         } while (code != GIF_OK);
  63.  
  64.         printf("P3\n");
  65.         printf("# %s\n", argv[1]);
  66.         printf("# width                %u \n", gif.width);
  67.         printf("# height               %u \n", gif.height);
  68.         printf("# frame_count          %u \n", gif.frame_count);
  69.         printf("# frame_count_partial  %u \n", gif.frame_count_partial);
  70.         printf("# loop_count           %u \n", gif.loop_count);
  71.         printf("%u %u 256\n", gif.width, gif.height * gif.frame_count);
  72.  
  73.         /* decode the frames */
  74.         for (i = 0; i != gif.frame_count; i++) {
  75.                 unsigned int row, col;
  76.                 unsigned char *image;
  77.  
  78.                 code = gif_decode_frame(&gif, i);
  79.                 if (code != GIF_OK)
  80.                         warning("gif_decode_frame", code);
  81.  
  82.                 printf("# frame %u:\n", i);
  83.                 image = (unsigned char *) gif.frame_image;
  84.                 for (row = 0; row != gif.height; row++) {
  85.                         for (col = 0; col != gif.width; col++) {
  86.                                 size_t z = (row * gif.width + col) * 4;
  87.                                 printf("%u %u %u ",
  88.                                         (unsigned char) image[z],
  89.                                         (unsigned char) image[z + 1],
  90.                                         (unsigned char) image[z + 2]);
  91.                         }
  92.                         printf("\n");
  93.                 }
  94.         }
  95.  
  96.         /* clean up */
  97.         gif_finalise(&gif);
  98.         free(data);
  99.  
  100.         return 0;
  101. }
  102.  
  103.  
  104. unsigned char *load_file(const char *path, size_t *data_size)
  105. {
  106.         FILE *fd;
  107.         struct stat sb;
  108.         unsigned char *buffer;
  109.         size_t size;
  110.         size_t n;
  111.  
  112.         fd = fopen(path, "rb");
  113.         if (!fd) {
  114.                 perror(path);
  115.                 exit(EXIT_FAILURE);
  116.         }
  117.  
  118.         if (stat(path, &sb)) {
  119.                 perror(path);
  120.                 exit(EXIT_FAILURE);
  121.         }
  122.         size = sb.st_size;
  123.  
  124.         buffer = malloc(size);
  125.         if (!buffer) {
  126.                 fprintf(stderr, "Unable to allocate %lld bytes\n",
  127.                                 (long long) size);
  128.                 exit(EXIT_FAILURE);
  129.         }
  130.  
  131.         n = fread(buffer, 1, size, fd);
  132.         if (n != size) {
  133.                 perror(path);
  134.                 exit(EXIT_FAILURE);
  135.         }
  136.  
  137.         fclose(fd);
  138.  
  139.         *data_size = size;
  140.         return buffer;
  141. }
  142.  
  143.  
  144. void warning(const char *context, gif_result code)
  145. {
  146.         fprintf(stderr, "%s failed: ", context);
  147.         switch (code)
  148.         {
  149.         case GIF_INSUFFICIENT_FRAME_DATA:
  150.                 fprintf(stderr, "GIF_INSUFFICIENT_FRAME_DATA");
  151.                 break;
  152.         case GIF_FRAME_DATA_ERROR:
  153.                 fprintf(stderr, "GIF_FRAME_DATA_ERROR");
  154.                 break;
  155.         case GIF_INSUFFICIENT_DATA:
  156.                 fprintf(stderr, "GIF_INSUFFICIENT_DATA");
  157.                 break;
  158.         case GIF_DATA_ERROR:
  159.                 fprintf(stderr, "GIF_DATA_ERROR");
  160.                 break;
  161.         case GIF_INSUFFICIENT_MEMORY:
  162.                 fprintf(stderr, "GIF_INSUFFICIENT_MEMORY");
  163.                 break;
  164.         default:
  165.                 fprintf(stderr, "unknown code %i", code);
  166.                 break;
  167.         }
  168.         fprintf(stderr, "\n");
  169. }
  170.  
  171.  
  172. void *bitmap_create(int width, int height)
  173. {
  174.         return calloc(width * height, 4);
  175. }
  176.  
  177.  
  178. void bitmap_set_opaque(void *bitmap, bool opaque)
  179. {
  180.         (void) opaque;  /* unused */
  181.         assert(bitmap);
  182. }
  183.  
  184.  
  185. bool bitmap_test_opaque(void *bitmap)
  186. {
  187.         assert(bitmap);
  188.         return false;
  189. }
  190.  
  191.  
  192. unsigned char *bitmap_get_buffer(void *bitmap)
  193. {
  194.         assert(bitmap);
  195.         return bitmap;
  196. }
  197.  
  198.  
  199. void bitmap_destroy(void *bitmap)
  200. {
  201.         assert(bitmap);
  202.         free(bitmap);
  203. }
  204.  
  205.  
  206. void bitmap_modified(void *bitmap)
  207. {
  208.         assert(bitmap);
  209.         return;
  210. }
  211.  
  212.