From cc5dedc259c4157516915e109b77ac88b9943a55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 10 Jun 2020 18:36:54 +0200 Subject: [PATCH] sixel: do not reset palette after each image A client can re-use the palette between images. Resetting the palette breaks this. Now we initialize the palette on demand, and resets it when the palette size is changed (by the client). --- CHANGELOG.md | 2 ++ sixel.c | 23 ++++++++++++++++++----- sixel.h | 2 ++ terminal.c | 1 + 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f91a08d..030d6c7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,8 @@ `\E[J3` was executed. * Assert (debug builds) when an `\e]4` OSC escape was not followed by a `;`. +* Palette re-use in sixel images. Previously, the palette was reset + after each image. ### Security diff --git a/sixel.c b/sixel.c index 5db9c42c..d691507c 100644 --- a/sixel.c +++ b/sixel.c @@ -12,10 +12,15 @@ static size_t count; +void +sixel_fini(struct terminal *term) +{ + free(term->sixel.palette); +} + void sixel_init(struct terminal *term) { - assert(term->sixel.palette == NULL); assert(term->sixel.image.data == NULL); assert(term->sixel.palette_size <= SIXEL_MAX_COLORS); @@ -26,11 +31,15 @@ sixel_init(struct terminal *term) term->sixel.param = 0; term->sixel.param_idx = 0; memset(term->sixel.params, 0, sizeof(term->sixel.params)); - term->sixel.palette = calloc(term->sixel.palette_size, sizeof(term->sixel.palette[0])); term->sixel.image.data = malloc(1 * 6 * sizeof(term->sixel.image.data[0])); term->sixel.image.width = 1; term->sixel.image.height = 6; + if (term->sixel.palette == NULL) { + term->sixel.palette = calloc( + term->sixel.palette_size, sizeof(term->sixel.palette[0])); + } + for (size_t i = 0; i < 1 * 6; i++) term->sixel.image.data[i] = term->colors.alpha / 256u << 24 | term->colors.bg; @@ -139,9 +148,6 @@ sixel_delete_at_cursor(struct terminal *term) void sixel_unhook(struct terminal *term) { - free(term->sixel.palette); - term->sixel.palette = NULL; - sixel_delete_at_cursor(term); struct sixel image = { @@ -489,6 +495,10 @@ void sixel_colors_reset(struct terminal *term) { LOG_DBG("sixel palette size reset to %u", SIXEL_MAX_COLORS); + + free(term->sixel.palette); + term->sixel.palette = NULL; + term->sixel.palette_size = SIXEL_MAX_COLORS; sixel_colors_report_current(term); } @@ -499,6 +509,9 @@ sixel_colors_set(struct terminal *term, unsigned count) unsigned new_palette_size = min(max(2, count), SIXEL_MAX_COLORS); LOG_DBG("sixel palette size set to %u", new_palette_size); + free(term->sixel.palette); + term->sixel.palette = NULL; + term->sixel.palette_size = new_palette_size; sixel_colors_report_current(term); } diff --git a/sixel.h b/sixel.h index 13eff024..a10f14f2 100644 --- a/sixel.h +++ b/sixel.h @@ -4,6 +4,8 @@ #define SIXEL_MAX_COLORS 1024u +void sixel_fini(struct terminal *term); + void sixel_init(struct terminal *term); void sixel_put(struct terminal *term, uint8_t c); void sixel_unhook(struct terminal *term); diff --git a/terminal.c b/terminal.c index f43c7320..74e46b7b 100644 --- a/terminal.c +++ b/terminal.c @@ -1168,6 +1168,7 @@ term_destroy(struct terminal *term) tll_foreach(term->alt.sixel_images, it) sixel_destroy(&it->item); tll_free(term->alt.sixel_images); + sixel_fini(term); free(term->foot_exe); free(term->cwd);