summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2022-02-22 18:47:58 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2022-02-23 16:13:14 +0000
commit88a078653a15d157b7c6f3ba57211f11f9121dab (patch)
tree2bf229caf8d28d3a1fee9c48f584cacdee49f334
parent0526c55f20ee7480533567fad62ea00e6bf31786 (diff)
downloadlibnsgif-88a078653a15d157b7c6f3ba57211f11f9121dab.tar.gz
libnsgif-88a078653a15d157b7c6f3ba57211f11f9121dab.tar.bz2
Test: Update decode test to new API.
-rw-r--r--test/decode_gif.c143
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;