Gitweb links:

...log 
http://git.netsurf-browser.org/libnsgif.git/shortlog/30b1b0baa029c809fd104f0013454c408cdc1418
...commit 
http://git.netsurf-browser.org/libnsgif.git/commit/30b1b0baa029c809fd104f0013454c408cdc1418
...tree 
http://git.netsurf-browser.org/libnsgif.git/tree/30b1b0baa029c809fd104f0013454c408cdc1418

The branch, master has been updated
       via  30b1b0baa029c809fd104f0013454c408cdc1418 (commit)
      from  ee6294d3f46d41a3f279adb147a386b10e96a5aa (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=30b1b0baa029c809fd104f0013454c408cdc1418
commit 30b1b0baa029c809fd104f0013454c408cdc1418
Author: Vincent Sanders <[email protected]>
Commit: Vincent Sanders <[email protected]>

    improve gif test decoder to limit image size and output to file

diff --git a/test/decode_gif.c b/test/decode_gif.c
index 2d2f37a..3ada667 100644
--- a/test/decode_gif.c
+++ b/test/decode_gif.c
@@ -17,199 +17,216 @@
 
 #include "../include/libnsgif.h"
 
-unsigned char *load_file(const char *path, size_t *data_size);
-void warning(const char *context, int code);
-void *bitmap_create(int width, int height);
-void bitmap_set_opaque(void *bitmap, bool opaque);
-bool bitmap_test_opaque(void *bitmap);
-unsigned char *bitmap_get_buffer(void *bitmap);
-void bitmap_destroy(void *bitmap);
-void bitmap_modified(void *bitmap);
+#define BYTES_PER_PIXEL 4
+#define MAX_IMAGE_BYTES (48 * 1024 * 1024)
 
 
-int main(int argc, char *argv[])
+static void *bitmap_create(int width, int height)
 {
-       gif_bitmap_callback_vt bitmap_callbacks = {
-               bitmap_create,
-               bitmap_destroy,
-               bitmap_get_buffer,
-               bitmap_set_opaque,
-               bitmap_test_opaque,
-               bitmap_modified
-       };
-       gif_animation gif;
-       size_t size;
-       gif_result code;
-       unsigned int i;
-
-       if (argc != 2) {
-               fprintf(stderr, "Usage: %s image.gif\n", argv[0]);
-               return 1;
-       }
-
-       /* create our gif animation */
-       gif_create(&gif, &bitmap_callbacks);
-
-       /* load file into memory */
-       unsigned char *data = load_file(argv[1], &size);
-
-       /* begin decoding */
-       do {
-               code = gif_initialise(&gif, size, data);
-               if (code != GIF_OK && code != GIF_WORKING) {
-                       warning("gif_initialise", code);
-                       exit(1);
-               }
-       } while (code != GIF_OK);
-
-       printf("P3\n");
-       printf("# %s\n", argv[1]);
-       printf("# width                %u \n", gif.width);
-       printf("# height               %u \n", gif.height);
-       printf("# frame_count          %u \n", gif.frame_count);
-       printf("# frame_count_partial  %u \n", gif.frame_count_partial);
-       printf("# loop_count           %u \n", gif.loop_count);
-       printf("%u %u 256\n", gif.width, gif.height * gif.frame_count);
-
-       /* decode the frames */
-       for (i = 0; i != gif.frame_count; i++) {
-               unsigned int row, col;
-               unsigned char *image;
-
-               code = gif_decode_frame(&gif, i);
-               if (code != GIF_OK)
-                       warning("gif_decode_frame", code);
-
-               printf("# frame %u:\n", i);
-               image = (unsigned char *) gif.frame_image;
-               for (row = 0; row != gif.height; row++) {
-                       for (col = 0; col != gif.width; col++) {
-                               size_t z = (row * gif.width + col) * 4;
-                               printf("%u %u %u ",
-                                       (unsigned char) image[z],
-                                       (unsigned char) image[z + 1],
-                                       (unsigned char) image[z + 2]);
-                       }
-                       printf("\n");
-               }
-       }
-
-       /* clean up */
-       gif_finalise(&gif);
-       free(data);
-
-       return 0;
+        /* ensure a stupidly large bitmap is not created */
+        if (((long long)width * (long long)height) > 
(MAX_IMAGE_BYTES/BYTES_PER_PIXEL)) {
+                return NULL;
+        }
+        return calloc(width * height, BYTES_PER_PIXEL);
 }
 
 
-unsigned char *load_file(const char *path, size_t *data_size)
+static void bitmap_set_opaque(void *bitmap, bool opaque)
 {
-       FILE *fd;
-       struct stat sb;
-       unsigned char *buffer;
-       size_t size;
-       size_t n;
-
-       fd = fopen(path, "rb");
-       if (!fd) {
-               perror(path);
-               exit(EXIT_FAILURE);
-       }
-
-       if (stat(path, &sb)) {
-               perror(path);
-               exit(EXIT_FAILURE);
-       }
-       size = sb.st_size;
-
-       buffer = malloc(size);
-       if (!buffer) {
-               fprintf(stderr, "Unable to allocate %lld bytes\n",
-                               (long long) size);
-               exit(EXIT_FAILURE);
-       }
-
-       n = fread(buffer, 1, size, fd);
-       if (n != size) {
-               perror(path);
-               exit(EXIT_FAILURE);
-       }
-
-       fclose(fd);
-
-       *data_size = size;
-       return buffer;
+        (void) opaque;  /* unused */
+        (void) bitmap;  /* unused */
+        assert(bitmap);
 }
 
 
-void warning(const char *context, gif_result code)
+static bool bitmap_test_opaque(void *bitmap)
 {
-       fprintf(stderr, "%s failed: ", context);
-       switch (code)
-       {
-       case GIF_INSUFFICIENT_FRAME_DATA:
-               fprintf(stderr, "GIF_INSUFFICIENT_FRAME_DATA");
-               break;
-       case GIF_FRAME_DATA_ERROR:
-               fprintf(stderr, "GIF_FRAME_DATA_ERROR");
-               break;
-       case GIF_INSUFFICIENT_DATA:
-               fprintf(stderr, "GIF_INSUFFICIENT_DATA");
-               break;
-       case GIF_DATA_ERROR:
-               fprintf(stderr, "GIF_DATA_ERROR");
-               break;
-       case GIF_INSUFFICIENT_MEMORY:
-               fprintf(stderr, "GIF_INSUFFICIENT_MEMORY");
-               break;
-       default:
-               fprintf(stderr, "unknown code %i", code);
-               break;
-       }
-       fprintf(stderr, "\n");
+        (void) bitmap;  /* unused */
+        assert(bitmap);
+        return false;
 }
 
 
-void *bitmap_create(int width, int height)
+static unsigned char *bitmap_get_buffer(void *bitmap)
 {
-       return calloc(width * height, 4);
+        assert(bitmap);
+        return bitmap;
 }
 
 
-void bitmap_set_opaque(void *bitmap, bool opaque)
+static void bitmap_destroy(void *bitmap)
 {
-       (void) opaque;  /* unused */
-       (void) bitmap;  /* unused */
-       assert(bitmap);
+        assert(bitmap);
+        free(bitmap);
 }
 
 
-bool bitmap_test_opaque(void *bitmap)
+static void bitmap_modified(void *bitmap)
 {
-       (void) bitmap;  /* unused */
-       assert(bitmap);
-       return false;
+        (void) bitmap;  /* unused */
+        assert(bitmap);
+        return;
 }
 
-
-unsigned char *bitmap_get_buffer(void *bitmap)
+static unsigned char *load_file(const char *path, size_t *data_size)
 {
-       assert(bitmap);
-       return bitmap;
+        FILE *fd;
+        struct stat sb;
+        unsigned char *buffer;
+        size_t size;
+        size_t n;
+
+        fd = fopen(path, "rb");
+        if (!fd) {
+                perror(path);
+                exit(EXIT_FAILURE);
+        }
+
+        if (stat(path, &sb)) {
+                perror(path);
+                exit(EXIT_FAILURE);
+        }
+        size = sb.st_size;
+
+        buffer = malloc(size);
+        if (!buffer) {
+                fprintf(stderr, "Unable to allocate %lld bytes\n",
+                        (long long) size);
+                exit(EXIT_FAILURE);
+        }
+
+        n = fread(buffer, 1, size, fd);
+        if (n != size) {
+                perror(path);
+                exit(EXIT_FAILURE);
+        }
+
+        fclose(fd);
+
+        *data_size = size;
+        return buffer;
 }
 
 
-void bitmap_destroy(void *bitmap)
+static void warning(const char *context, gif_result code)
 {
-       assert(bitmap);
-       free(bitmap);
+        fprintf(stderr, "%s failed: ", context);
+        switch (code)
+        {
+        case GIF_INSUFFICIENT_FRAME_DATA:
+                fprintf(stderr, "GIF_INSUFFICIENT_FRAME_DATA");
+                break;
+        case GIF_FRAME_DATA_ERROR:
+                fprintf(stderr, "GIF_FRAME_DATA_ERROR");
+                break;
+        case GIF_INSUFFICIENT_DATA:
+                fprintf(stderr, "GIF_INSUFFICIENT_DATA");
+                break;
+        case GIF_DATA_ERROR:
+                fprintf(stderr, "GIF_DATA_ERROR");
+                break;
+        case GIF_INSUFFICIENT_MEMORY:
+                fprintf(stderr, "GIF_INSUFFICIENT_MEMORY");
+                break;
+        default:
+                fprintf(stderr, "unknown code %i", code);
+                break;
+        }
+        fprintf(stderr, "\n");
 }
 
-
-void bitmap_modified(void *bitmap)
+static void write_ppm(FILE* fh, const char *name, gif_animation *gif)
 {
-       (void) bitmap;  /* unused */
-       assert(bitmap);
-       return;
+        unsigned int i;
+        gif_result code;
+
+        fprintf(fh, "P3\n");
+        fprintf(fh, "# %s\n", name);
+        fprintf(fh, "# width                %u \n", gif->width);
+        fprintf(fh, "# height               %u \n", gif->height);
+        fprintf(fh, "# frame_count          %u \n", gif->frame_count);
+        fprintf(fh, "# frame_count_partial  %u \n", gif->frame_count_partial);
+        fprintf(fh, "# loop_count           %u \n", gif->loop_count);
+        fprintf(fh, "%u %u 256\n", gif->width, gif->height * gif->frame_count);
+
+        /* decode the frames */
+        for (i = 0; i != gif->frame_count; i++) {
+                unsigned int row, col;
+                unsigned char *image;
+
+                code = gif_decode_frame(gif, i);
+                if (code != GIF_OK)
+                        warning("gif_decode_frame", code);
+
+                printf("# frame %u:\n", i);
+                image = (unsigned char *) gif->frame_image;
+                for (row = 0; row != gif->height; row++) {
+                        for (col = 0; col != gif->width; col++) {
+                                size_t z = (row * gif->width + col) * 4;
+                                fprintf(fh, "%u %u %u ",
+                                        (unsigned char) image[z],
+                                        (unsigned char) image[z + 1],
+                                        (unsigned char) image[z + 2]);
+                        }
+                        fprintf(fh, "\n");
+                }
+        }
+
 }
 
+int main(int argc, char *argv[])
+{
+        gif_bitmap_callback_vt bitmap_callbacks = {
+                bitmap_create,
+                bitmap_destroy,
+                bitmap_get_buffer,
+                bitmap_set_opaque,
+                bitmap_test_opaque,
+                bitmap_modified
+        };
+        gif_animation gif;
+        size_t size;
+        gif_result code;
+        unsigned char *data;
+        FILE *outf = stdout;
+
+        if (argc < 2) {
+                fprintf(stderr, "Usage: %s image.gif [out]\n", argv[0]);
+                return 1;
+        }
+
+        if (argc > 2) {
+                outf = fopen(argv[2], "w+");
+                if (outf == NULL) {
+                        fprintf(stderr, "Unable to open %s for writing\n", 
argv[2]);
+                        return 2;
+                }
+        }
+
+        /* create our gif animation */
+        gif_create(&gif, &bitmap_callbacks);
+
+        /* load file into memory */
+        data = load_file(argv[1], &size);
+
+        /* begin decoding */
+        do {
+                code = gif_initialise(&gif, size, data);
+                if (code != GIF_OK && code != GIF_WORKING) {
+                        warning("gif_initialise", code);
+                        return 1;
+                }
+        } while (code != GIF_OK);
+
+        write_ppm(outf, argv[1], &gif);
+
+        if (argc > 2) {
+                fclose(outf);
+        }
+
+        /* clean up */
+        gif_finalise(&gif);
+        free(data);
+
+        return 0;
+}


-----------------------------------------------------------------------

Summary of changes:
 test/decode_gif.c |  339 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 178 insertions(+), 161 deletions(-)

diff --git a/test/decode_gif.c b/test/decode_gif.c
index 2d2f37a..3ada667 100644
--- a/test/decode_gif.c
+++ b/test/decode_gif.c
@@ -17,199 +17,216 @@
 
 #include "../include/libnsgif.h"
 
-unsigned char *load_file(const char *path, size_t *data_size);
-void warning(const char *context, int code);
-void *bitmap_create(int width, int height);
-void bitmap_set_opaque(void *bitmap, bool opaque);
-bool bitmap_test_opaque(void *bitmap);
-unsigned char *bitmap_get_buffer(void *bitmap);
-void bitmap_destroy(void *bitmap);
-void bitmap_modified(void *bitmap);
+#define BYTES_PER_PIXEL 4
+#define MAX_IMAGE_BYTES (48 * 1024 * 1024)
 
 
-int main(int argc, char *argv[])
+static void *bitmap_create(int width, int height)
 {
-       gif_bitmap_callback_vt bitmap_callbacks = {
-               bitmap_create,
-               bitmap_destroy,
-               bitmap_get_buffer,
-               bitmap_set_opaque,
-               bitmap_test_opaque,
-               bitmap_modified
-       };
-       gif_animation gif;
-       size_t size;
-       gif_result code;
-       unsigned int i;
-
-       if (argc != 2) {
-               fprintf(stderr, "Usage: %s image.gif\n", argv[0]);
-               return 1;
-       }
-
-       /* create our gif animation */
-       gif_create(&gif, &bitmap_callbacks);
-
-       /* load file into memory */
-       unsigned char *data = load_file(argv[1], &size);
-
-       /* begin decoding */
-       do {
-               code = gif_initialise(&gif, size, data);
-               if (code != GIF_OK && code != GIF_WORKING) {
-                       warning("gif_initialise", code);
-                       exit(1);
-               }
-       } while (code != GIF_OK);
-
-       printf("P3\n");
-       printf("# %s\n", argv[1]);
-       printf("# width                %u \n", gif.width);
-       printf("# height               %u \n", gif.height);
-       printf("# frame_count          %u \n", gif.frame_count);
-       printf("# frame_count_partial  %u \n", gif.frame_count_partial);
-       printf("# loop_count           %u \n", gif.loop_count);
-       printf("%u %u 256\n", gif.width, gif.height * gif.frame_count);
-
-       /* decode the frames */
-       for (i = 0; i != gif.frame_count; i++) {
-               unsigned int row, col;
-               unsigned char *image;
-
-               code = gif_decode_frame(&gif, i);
-               if (code != GIF_OK)
-                       warning("gif_decode_frame", code);
-
-               printf("# frame %u:\n", i);
-               image = (unsigned char *) gif.frame_image;
-               for (row = 0; row != gif.height; row++) {
-                       for (col = 0; col != gif.width; col++) {
-                               size_t z = (row * gif.width + col) * 4;
-                               printf("%u %u %u ",
-                                       (unsigned char) image[z],
-                                       (unsigned char) image[z + 1],
-                                       (unsigned char) image[z + 2]);
-                       }
-                       printf("\n");
-               }
-       }
-
-       /* clean up */
-       gif_finalise(&gif);
-       free(data);
-
-       return 0;
+        /* ensure a stupidly large bitmap is not created */
+        if (((long long)width * (long long)height) > 
(MAX_IMAGE_BYTES/BYTES_PER_PIXEL)) {
+                return NULL;
+        }
+        return calloc(width * height, BYTES_PER_PIXEL);
 }
 
 
-unsigned char *load_file(const char *path, size_t *data_size)
+static void bitmap_set_opaque(void *bitmap, bool opaque)
 {
-       FILE *fd;
-       struct stat sb;
-       unsigned char *buffer;
-       size_t size;
-       size_t n;
-
-       fd = fopen(path, "rb");
-       if (!fd) {
-               perror(path);
-               exit(EXIT_FAILURE);
-       }
-
-       if (stat(path, &sb)) {
-               perror(path);
-               exit(EXIT_FAILURE);
-       }
-       size = sb.st_size;
-
-       buffer = malloc(size);
-       if (!buffer) {
-               fprintf(stderr, "Unable to allocate %lld bytes\n",
-                               (long long) size);
-               exit(EXIT_FAILURE);
-       }
-
-       n = fread(buffer, 1, size, fd);
-       if (n != size) {
-               perror(path);
-               exit(EXIT_FAILURE);
-       }
-
-       fclose(fd);
-
-       *data_size = size;
-       return buffer;
+        (void) opaque;  /* unused */
+        (void) bitmap;  /* unused */
+        assert(bitmap);
 }
 
 
-void warning(const char *context, gif_result code)
+static bool bitmap_test_opaque(void *bitmap)
 {
-       fprintf(stderr, "%s failed: ", context);
-       switch (code)
-       {
-       case GIF_INSUFFICIENT_FRAME_DATA:
-               fprintf(stderr, "GIF_INSUFFICIENT_FRAME_DATA");
-               break;
-       case GIF_FRAME_DATA_ERROR:
-               fprintf(stderr, "GIF_FRAME_DATA_ERROR");
-               break;
-       case GIF_INSUFFICIENT_DATA:
-               fprintf(stderr, "GIF_INSUFFICIENT_DATA");
-               break;
-       case GIF_DATA_ERROR:
-               fprintf(stderr, "GIF_DATA_ERROR");
-               break;
-       case GIF_INSUFFICIENT_MEMORY:
-               fprintf(stderr, "GIF_INSUFFICIENT_MEMORY");
-               break;
-       default:
-               fprintf(stderr, "unknown code %i", code);
-               break;
-       }
-       fprintf(stderr, "\n");
+        (void) bitmap;  /* unused */
+        assert(bitmap);
+        return false;
 }
 
 
-void *bitmap_create(int width, int height)
+static unsigned char *bitmap_get_buffer(void *bitmap)
 {
-       return calloc(width * height, 4);
+        assert(bitmap);
+        return bitmap;
 }
 
 
-void bitmap_set_opaque(void *bitmap, bool opaque)
+static void bitmap_destroy(void *bitmap)
 {
-       (void) opaque;  /* unused */
-       (void) bitmap;  /* unused */
-       assert(bitmap);
+        assert(bitmap);
+        free(bitmap);
 }
 
 
-bool bitmap_test_opaque(void *bitmap)
+static void bitmap_modified(void *bitmap)
 {
-       (void) bitmap;  /* unused */
-       assert(bitmap);
-       return false;
+        (void) bitmap;  /* unused */
+        assert(bitmap);
+        return;
 }
 
-
-unsigned char *bitmap_get_buffer(void *bitmap)
+static unsigned char *load_file(const char *path, size_t *data_size)
 {
-       assert(bitmap);
-       return bitmap;
+        FILE *fd;
+        struct stat sb;
+        unsigned char *buffer;
+        size_t size;
+        size_t n;
+
+        fd = fopen(path, "rb");
+        if (!fd) {
+                perror(path);
+                exit(EXIT_FAILURE);
+        }
+
+        if (stat(path, &sb)) {
+                perror(path);
+                exit(EXIT_FAILURE);
+        }
+        size = sb.st_size;
+
+        buffer = malloc(size);
+        if (!buffer) {
+                fprintf(stderr, "Unable to allocate %lld bytes\n",
+                        (long long) size);
+                exit(EXIT_FAILURE);
+        }
+
+        n = fread(buffer, 1, size, fd);
+        if (n != size) {
+                perror(path);
+                exit(EXIT_FAILURE);
+        }
+
+        fclose(fd);
+
+        *data_size = size;
+        return buffer;
 }
 
 
-void bitmap_destroy(void *bitmap)
+static void warning(const char *context, gif_result code)
 {
-       assert(bitmap);
-       free(bitmap);
+        fprintf(stderr, "%s failed: ", context);
+        switch (code)
+        {
+        case GIF_INSUFFICIENT_FRAME_DATA:
+                fprintf(stderr, "GIF_INSUFFICIENT_FRAME_DATA");
+                break;
+        case GIF_FRAME_DATA_ERROR:
+                fprintf(stderr, "GIF_FRAME_DATA_ERROR");
+                break;
+        case GIF_INSUFFICIENT_DATA:
+                fprintf(stderr, "GIF_INSUFFICIENT_DATA");
+                break;
+        case GIF_DATA_ERROR:
+                fprintf(stderr, "GIF_DATA_ERROR");
+                break;
+        case GIF_INSUFFICIENT_MEMORY:
+                fprintf(stderr, "GIF_INSUFFICIENT_MEMORY");
+                break;
+        default:
+                fprintf(stderr, "unknown code %i", code);
+                break;
+        }
+        fprintf(stderr, "\n");
 }
 
-
-void bitmap_modified(void *bitmap)
+static void write_ppm(FILE* fh, const char *name, gif_animation *gif)
 {
-       (void) bitmap;  /* unused */
-       assert(bitmap);
-       return;
+        unsigned int i;
+        gif_result code;
+
+        fprintf(fh, "P3\n");
+        fprintf(fh, "# %s\n", name);
+        fprintf(fh, "# width                %u \n", gif->width);
+        fprintf(fh, "# height               %u \n", gif->height);
+        fprintf(fh, "# frame_count          %u \n", gif->frame_count);
+        fprintf(fh, "# frame_count_partial  %u \n", gif->frame_count_partial);
+        fprintf(fh, "# loop_count           %u \n", gif->loop_count);
+        fprintf(fh, "%u %u 256\n", gif->width, gif->height * gif->frame_count);
+
+        /* decode the frames */
+        for (i = 0; i != gif->frame_count; i++) {
+                unsigned int row, col;
+                unsigned char *image;
+
+                code = gif_decode_frame(gif, i);
+                if (code != GIF_OK)
+                        warning("gif_decode_frame", code);
+
+                printf("# frame %u:\n", i);
+                image = (unsigned char *) gif->frame_image;
+                for (row = 0; row != gif->height; row++) {
+                        for (col = 0; col != gif->width; col++) {
+                                size_t z = (row * gif->width + col) * 4;
+                                fprintf(fh, "%u %u %u ",
+                                        (unsigned char) image[z],
+                                        (unsigned char) image[z + 1],
+                                        (unsigned char) image[z + 2]);
+                        }
+                        fprintf(fh, "\n");
+                }
+        }
+
 }
 
+int main(int argc, char *argv[])
+{
+        gif_bitmap_callback_vt bitmap_callbacks = {
+                bitmap_create,
+                bitmap_destroy,
+                bitmap_get_buffer,
+                bitmap_set_opaque,
+                bitmap_test_opaque,
+                bitmap_modified
+        };
+        gif_animation gif;
+        size_t size;
+        gif_result code;
+        unsigned char *data;
+        FILE *outf = stdout;
+
+        if (argc < 2) {
+                fprintf(stderr, "Usage: %s image.gif [out]\n", argv[0]);
+                return 1;
+        }
+
+        if (argc > 2) {
+                outf = fopen(argv[2], "w+");
+                if (outf == NULL) {
+                        fprintf(stderr, "Unable to open %s for writing\n", 
argv[2]);
+                        return 2;
+                }
+        }
+
+        /* create our gif animation */
+        gif_create(&gif, &bitmap_callbacks);
+
+        /* load file into memory */
+        data = load_file(argv[1], &size);
+
+        /* begin decoding */
+        do {
+                code = gif_initialise(&gif, size, data);
+                if (code != GIF_OK && code != GIF_WORKING) {
+                        warning("gif_initialise", code);
+                        return 1;
+                }
+        } while (code != GIF_OK);
+
+        write_ppm(outf, argv[1], &gif);
+
+        if (argc > 2) {
+                fclose(outf);
+        }
+
+        /* clean up */
+        gif_finalise(&gif);
+        free(data);
+
+        return 0;
+}


-- 
NetSurf GIF Decoder

_______________________________________________
netsurf-commits mailing list
[email protected]
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org

Reply via email to