diff options
author | Michael Drake <tlsa@netsurf-browser.org> | 2022-02-22 18:47:58 +0000 |
---|---|---|
committer | Michael Drake <tlsa@netsurf-browser.org> | 2022-02-23 16:13:14 +0000 |
commit | 88a078653a15d157b7c6f3ba57211f11f9121dab (patch) | |
tree | 2bf229caf8d28d3a1fee9c48f584cacdee49f334 | |
parent | 0526c55f20ee7480533567fad62ea00e6bf31786 (diff) | |
download | libnsgif-88a078653a15d157b7c6f3ba57211f11f9121dab.tar.gz libnsgif-88a078653a15d157b7c6f3ba57211f11f9121dab.tar.bz2 |
Test: Update decode test to new API.
-rw-r--r-- | test/decode_gif.c | 143 |
1 files changed, 68 insertions, 75 deletions
diff --git a/test/decode_gif.c b/test/decode_gif.c index a20d5f4..5789c41 100644 --- a/test/decode_gif.c +++ b/test/decode_gif.c @@ -18,51 +18,28 @@ #include "../include/nsgif.h" #define BYTES_PER_PIXEL 4 -#define MAX_IMAGE_BYTES (48 * 1024 * 1024) static void *bitmap_create(int width, int height) { - /* ensure a stupidly large bitmap is not created */ - if (((long long)width * (long long)height) > (MAX_IMAGE_BYTES/BYTES_PER_PIXEL)) { + /* Ensure a stupidly large bitmap is not created */ + if (width > 4096 || height > 4096) { return NULL; } - return calloc(width * height, BYTES_PER_PIXEL); -} - -static void bitmap_set_opaque(void *bitmap, bool opaque) -{ - (void) opaque; /* unused */ - (void) bitmap; /* unused */ - assert(bitmap); -} -static bool bitmap_test_opaque(void *bitmap) -{ - (void) bitmap; /* unused */ - assert(bitmap); - return false; + return calloc(width * height, BYTES_PER_PIXEL); } static unsigned char *bitmap_get_buffer(void *bitmap) { - assert(bitmap); return bitmap; } static void bitmap_destroy(void *bitmap) { - assert(bitmap); free(bitmap); } -static void bitmap_modified(void *bitmap) -{ - (void) bitmap; /* unused */ - assert(bitmap); - return; -} - -static unsigned char *load_file(const char *path, size_t *data_size) +static uint8_t *load_file(const char *path, size_t *data_size) { FILE *fd; struct stat sb; @@ -101,11 +78,10 @@ static unsigned char *load_file(const char *path, size_t *data_size) return buffer; } -static void warning(const char *context, nsgif_result code) +static void warning(const char *context, nsgif_result gif_res) { fprintf(stderr, "%s failed: ", context); - switch (code) - { + switch (gif_res) { case NSGIF_FRAME_DATA_ERROR: fprintf(stderr, "NSGIF_FRAME_DATA_ERROR"); break; @@ -119,52 +95,69 @@ static void warning(const char *context, nsgif_result code) fprintf(stderr, "NSGIF_INSUFFICIENT_MEMORY"); break; default: - fprintf(stderr, "unknown code %i", code); + fprintf(stderr, "unknown code %i", gif_res); break; } fprintf(stderr, "\n"); } -static void write_ppm(FILE* fh, const char *name, nsgif *gif, - bool no_write) +static void write_ppm(FILE* fh, const char *name, nsgif *gif, bool no_write) { - unsigned int i; - nsgif_result code; + nsgif_result gif_res; + uint32_t frame_prev = 0; + const nsgif_info_t *info; + + info = nsgif_get_info(gif); if (!no_write) { 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); + fprintf(fh, "# width %u \n", info->width); + fprintf(fh, "# height %u \n", info->height); + fprintf(fh, "# frame_count %u \n", info->frame_count); + fprintf(fh, "# loop_max %u \n", info->loop_max); + fprintf(fh, "%u %u 256\n", info->width, + info->height * info->frame_count); } /* decode the frames */ - for (i = 0; i != gif->frame_count; i++) { - unsigned int row, col; - unsigned char *image; + while (true) { + const uint32_t *buffer; + const uint8_t *image; + uint32_t frame_new; + uint32_t delay_cs; + nsgif_rect area; + + gif_res = nsgif_frame_prepare(gif, &area, + &delay_cs, &frame_new); + if (gif_res != NSGIF_OK) { + warning("nsgif_frame_prepare", gif_res); + return; + } - code = nsgif_decode_frame(gif, i); - if (code != NSGIF_OK) - warning("nsgif_decode_frame", code); + if (frame_new < frame_prev) { + /* Must be an animation that loops. We only care about + * decoding each frame once. */ + return; + } + frame_prev = frame_new; - if (!gif->frames[i].display) { - continue; + gif_res = nsgif_frame_decode(gif, frame_new, &buffer); + if (gif_res != NSGIF_OK) { + warning("nsgif_decode_frame", gif_res); + return; } if (!no_write) { - fprintf(fh, "# 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, "# frame %u:\n", frame_new); + image = (const uint8_t *) buffer; + for (uint32_t y = 0; y != info->height; y++) { + for (uint32_t x = 0; x != info->width; x++) { + size_t z = (y * info->width + x) * 4; fprintf(fh, "%u %u %u ", - (unsigned char) image[z], - (unsigned char) image[z + 1], - (unsigned char) image[z + 2]); + image[z], + image[z + 1], + image[z + 2]); } fprintf(fh, "\n"); } @@ -174,19 +167,16 @@ static void write_ppm(FILE* fh, const char *name, nsgif *gif, int main(int argc, char *argv[]) { - nsgif_bitmap_cb_vt bitmap_callbacks = { - bitmap_create, - bitmap_destroy, - bitmap_get_buffer, - bitmap_set_opaque, - bitmap_test_opaque, - bitmap_modified + const nsgif_bitmap_cb_vt bitmap_callbacks = { + .create = bitmap_create, + .destroy = bitmap_destroy, + .get_buffer = bitmap_get_buffer, }; - nsgif gif; + nsgif *gif; size_t size; - nsgif_result code; - unsigned char *data; + uint8_t *data; FILE *outf = stdout; + nsgif_result gif_res; bool no_write = false; if (argc < 2) { @@ -213,30 +203,33 @@ int main(int argc, char *argv[]) } /* create our gif animation */ - nsgif_create(&gif, &bitmap_callbacks); + gif_res = nsgif_create(&bitmap_callbacks, &gif); + if (gif_res != NSGIF_OK) { + return 1; + } /* load file into memory */ data = load_file(argv[1], &size); /* begin decoding */ do { - code = nsgif_initialise(&gif, size, data); - if (code != NSGIF_OK && code != NSGIF_WORKING) { - warning("nsgif_initialise", code); - nsgif_finalise(&gif); + gif_res = nsgif_data_scan(gif, size, data); + if (gif_res != NSGIF_OK && gif_res != NSGIF_WORKING) { + warning("nsgif_data_scan", gif_res); + nsgif_destroy(gif); free(data); return 1; } - } while (code != NSGIF_OK); + } while (gif_res != NSGIF_OK); - write_ppm(outf, argv[1], &gif, no_write); + write_ppm(outf, argv[1], gif, no_write); if (argc > 2 && !no_write) { fclose(outf); } /* clean up */ - nsgif_finalise(&gif); + nsgif_destroy(gif); free(data); return 0; |