mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
sixel: minor fixes after implementing support for non-1:1 aspect ratios
* Lazy initialize image height. This is necessary to prevent garbage from being rendered for "empty" sixels. * Fix plotting of non-1:1 pixels * Fix calculation of height in resize(), for non-1:1 aspect ratios
This commit is contained in:
parent
774570ec41
commit
1eb90b2405
1 changed files with 29 additions and 17 deletions
46
sixel.c
46
sixel.c
|
|
@ -46,10 +46,10 @@ sixel_init(struct terminal *term, int p1, int p2, int p3)
|
|||
(p1 == 7 || p1 == 8 || p1 == 9) ? 1 : 2;
|
||||
|
||||
LOG_DBG("initializing sixel with "
|
||||
"p1=%d (pan=%d, pad=%d, AR=%d:%d), "
|
||||
"p2=%d (transparent=%d), "
|
||||
"p1=%d (pan=%d, pad=%d, aspect-ratio=%d:%d), "
|
||||
"p2=%d (transparent=%s), "
|
||||
"p3=%d (ignored)",
|
||||
p1, pan, pad, pan, pad, p2, p2 == 1, p3);
|
||||
p1, pan, pad, pan, pad, p2, p2 == 1 ? "yes" : "no", p3);
|
||||
|
||||
term->sixel.state = SIXEL_DECSIXEL;
|
||||
term->sixel.pos = (struct coord){0, 0};
|
||||
|
|
@ -63,7 +63,7 @@ sixel_init(struct terminal *term, int p1, int p2, int p3)
|
|||
term->sixel.transparent_bg = p2 == 1;
|
||||
term->sixel.image.data = NULL;
|
||||
term->sixel.image.width = 0;
|
||||
term->sixel.image.height = 6 * pan;
|
||||
term->sixel.image.height = 0;
|
||||
|
||||
/* TODO: default palette */
|
||||
|
||||
|
|
@ -1119,10 +1119,6 @@ sixel_unhook(struct terminal *term)
|
|||
static void
|
||||
resize_horizontally(struct terminal *term, int new_width)
|
||||
{
|
||||
LOG_DBG("resizing image horizontally: %dx(%d) -> %dx(%d)",
|
||||
term->sixel.image.width, term->sixel.image.height,
|
||||
new_width, term->sixel.image.height);
|
||||
|
||||
if (unlikely(new_width > term->sixel.max_width)) {
|
||||
LOG_WARN("maximum image dimensions exceeded, truncating");
|
||||
new_width = term->sixel.max_width;
|
||||
|
|
@ -1131,11 +1127,23 @@ resize_horizontally(struct terminal *term, int new_width)
|
|||
if (unlikely(term->sixel.image.width == new_width))
|
||||
return;
|
||||
|
||||
const int sixel_row_height = 6 * term->sixel.pan;
|
||||
|
||||
uint32_t *old_data = term->sixel.image.data;
|
||||
const int old_width = term->sixel.image.width;
|
||||
const int height = term->sixel.image.height;
|
||||
|
||||
const int sixel_row_height = 6 * term->sixel.pan;
|
||||
int height;
|
||||
if (unlikely(term->sixel.image.height == 0)) {
|
||||
/* Lazy initialize height on first printed sixel */
|
||||
xassert(old_width == 0);
|
||||
term->sixel.image.height = height = sixel_row_height;
|
||||
} else
|
||||
height = term->sixel.image.height;
|
||||
|
||||
LOG_DBG("resizing image horizontally: %dx(%d) -> %dx(%d)",
|
||||
term->sixel.image.width, term->sixel.image.height,
|
||||
new_width, height);
|
||||
|
||||
int alloc_height = (height + sixel_row_height - 1) / sixel_row_height * sixel_row_height;
|
||||
|
||||
xassert(new_width > 0);
|
||||
|
|
@ -1231,10 +1239,11 @@ resize(struct terminal *term, int new_width, int new_height)
|
|||
const int old_width = term->sixel.image.width;
|
||||
const int old_height = term->sixel.image.height;
|
||||
|
||||
const int sixel_row_height = 6 * term->sixel.pan;
|
||||
int alloc_new_width = new_width;
|
||||
int alloc_new_height = (new_height + 6 - 1) / 6 * 6;
|
||||
int alloc_new_height = (new_height + sixel_row_height - 1) / sixel_row_height * sixel_row_height;
|
||||
xassert(alloc_new_height >= new_height);
|
||||
xassert(alloc_new_height - new_height < 6);
|
||||
xassert(alloc_new_height - new_height < sixel_row_height);
|
||||
|
||||
uint32_t *new_data = NULL;
|
||||
uint32_t bg = term->sixel.default_bg;
|
||||
|
|
@ -1287,13 +1296,16 @@ sixel_add(struct terminal *term, int col, int width, uint32_t color, uint8_t six
|
|||
xassert(term->sixel.pos.col < term->sixel.image.width);
|
||||
xassert(term->sixel.pos.row < term->sixel.image.height);
|
||||
|
||||
const int pan = term->sixel.pan;
|
||||
size_t ofs = term->sixel.row_byte_ofs + col;
|
||||
uint32_t *data = &term->sixel.image.data[ofs];
|
||||
|
||||
for (int i = 0; i < 6 * term->sixel.pan; i++, sixel >>= 1, data += width) {
|
||||
for (int i = 0; i < 6; i++, sixel >>= 1) {
|
||||
if (sixel & 1) {
|
||||
*data = color;
|
||||
}
|
||||
for (int r = 0; r < pan; r++, data += width)
|
||||
*data = color;
|
||||
} else
|
||||
data += width * pan;
|
||||
}
|
||||
|
||||
xassert(sixel == 0);
|
||||
|
|
@ -1425,8 +1437,8 @@ decgra(struct terminal *term, uint8_t c)
|
|||
term->sixel.pan = pan;
|
||||
term->sixel.pad = pad;
|
||||
|
||||
LOG_DBG("pan=%u, pad=%u (aspect ratio = %u), size=%ux%u",
|
||||
pan, pad, pan / pad, ph, pv);
|
||||
LOG_DBG("pan=%u, pad=%u (aspect ratio = %d:%d), size=%ux%u",
|
||||
pan, pad, pan, pad, ph, pv);
|
||||
|
||||
if (ph >= term->sixel.image.height && pv >= term->sixel.image.width &&
|
||||
ph <= term->sixel.max_height && pv <= term->sixel.max_width)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue