sixel: don't allow pan/pad changes after sixel data has been emitted

Changing pan/pad changes the sixel's aspect ratio. While I don't know
for certain what a real VT340 would do, I suspect it would change the
aspect ratio of all subsequent sixels, but not those already emitted.

The way we implement sixels in foot, makes this behavior hard to
implement. We currently don't resize the image properly if the aspect
ratio is changed, but not the RA area. We have code that assumes all
sixel lines have the same aspect ratio, etc.

Since no "normal" applications change the aspect ratio in the middle
of a sixel, simply disallow it, and print a warning.

This also fixes a crash, when writing sixels after having modified the
aspect ratio.
This commit is contained in:
Daniel Eklöf 2024-04-15 16:07:47 +02:00
parent 0ab05f4807
commit 3d2588edf8
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 26 additions and 3 deletions

View file

@ -62,6 +62,9 @@
### Removed
### Fixed
* Crash when changing aspect ratio of a sixel, in the middle of the
sixel data (this is unsupported in foot, but should of course not
result in a crash).
* Crash when printing double-width (or longer) characters to, or near,
the last column, when auto-wrap (private mode 7) has been disabled.
* Dynamically sized sixel being trimmed to nothing.

26
sixel.c
View file

@ -1852,12 +1852,32 @@ decgra(struct terminal *term, uint8_t c)
pan = pan > 0 ? pan : 1;
pad = pad > 0 ? pad : 1;
if (likely(term->sixel.image.width == 0 &&
term->sixel.image.height == 0))
{
term->sixel.pan = pan;
term->sixel.pad = pad;
} else {
/*
* Unsure what the VT340 does...
*
* We currently do *not* handle changing pan/pad in the
* middle of a sixel, since that means resizing/stretching
* the existing image.
*
* I'm *guessing* the VT340 simply changes the aspect
* ratio of all subsequent sixels. But, given the design
* of our implementation (the entire sixel is written to a
* single pixman image), we can't easily do that.
*/
LOG_WARN("sixel: unsupported: pan/pad changed after printing sixels");
pan = term->sixel.pan;
pad = term->sixel.pad;
}
pv *= pan;
ph *= pad;
term->sixel.pan = pan;
term->sixel.pad = pad;
LOG_DBG("pan=%u, pad=%u (aspect ratio = %d:%d), size=%ux%u",
pan, pad, pan, pad, ph, pv);