2021-04-06 20:39:02 (UTC-03:00)
Marcel Rodrigues <marcelgmr@gmail.com>
Add option to copy default palette to array.
diff --git a/README b/README index 1d1fd39..35b159e 100644 --- a/README +++ b/README @@ -61,6 +61,9 @@ default table is composed of the 16 standard VGA colors, plus the 216 web-safe colors (all combinations of RGB with only 6 valid values per channel), plus 24 grey colors equally spaced between black and white, excluding both. +If `depth` < 0 and `palette` is not NULL, then the default table with 2 ^ -depth +colors is used and it is stored in the array at the `palette` address. + If the `loop` parameter is zero, the resulting GIF will loop forever. If it is a positive number, the animation will be played that number of times. If `loop` is negative, no looping information is stored in the GIF file (for most GIF diff --git a/gifenc.c b/gifenc.c index c0e4e11..5be9ffe 100644 --- a/gifenc.c +++ b/gifenc.c @@ -70,6 +70,15 @@ del_trie(Node *root, int degree) free(root); } +#define write_and_store(s, dst, fd, src, n) \ +do { \ + write(fd, src, n); \ + if (s) { \ + memcpy(dst, src, n); \ + dst += n; \ + } \ +} while (0); + static void put_loop(ge_GIF *gif, uint16_t loop); ge_GIF * @@ -79,11 +88,11 @@ ge_new_gif( ) { int i, r, g, b, v; + int store_gct, custom_gct; ge_GIF *gif = calloc(1, sizeof(*gif) + 2*width*height); if (!gif) goto no_gif; gif->w = width; gif->h = height; - gif->depth = depth > 1 ? depth : 2; gif->frame = (uint8_t *) &gif[1]; gif->back = &gif->frame[width*height]; #ifdef _WIN32 @@ -99,18 +108,30 @@ ge_new_gif( write(gif->fd, "GIF89a", 6); write_num(gif->fd, width); write_num(gif->fd, height); - write(gif->fd, (uint8_t []) {0xF0 | (depth-1), 0x00, 0x00}, 3); + store_gct = custom_gct = 0; if (palette) { + if (depth < 0) + store_gct = 1; + else + custom_gct = 1; + } + if (depth < 0) + depth = -depth; + gif->depth = depth > 1 ? depth : 2; + write(gif->fd, (uint8_t []) {0xF0 | (depth-1), 0x00, 0x00}, 3); + if (custom_gct) { write(gif->fd, palette, 3 << depth); } else if (depth <= 4) { - write(gif->fd, vga, 3 << depth); + write_and_store(store_gct, palette, gif->fd, vga, 3 << depth); } else { - write(gif->fd, vga, sizeof(vga)); + write_and_store(store_gct, palette, gif->fd, vga, sizeof(vga)); i = 0x10; for (r = 0; r < 6; r++) { for (g = 0; g < 6; g++) { for (b = 0; b < 6; b++) { - write(gif->fd, (uint8_t []) {r*51, g*51, b*51}, 3); + write_and_store(store_gct, palette, gif->fd, + ((uint8_t []) {r*51, g*51, b*51}), 3 + ); if (++i == 1 << depth) goto done_gct; } @@ -118,7 +139,9 @@ ge_new_gif( } for (i = 1; i <= 24; i++) { v = i * 0xFF / 25; - write(gif->fd, (uint8_t []) {v, v, v}, 3); + write_and_store(store_gct, palette, gif->fd, + ((uint8_t []) {v, v, v}), 3 + ); } } done_gct: