Check out my first novel, midnight's simulacra!
Sixel: Difference between revisions
No edit summary |
|||
Line 1: | Line 1: | ||
Sixel ("six pixels") does not appear to have any true, up-to-date "standard". It seems to have been introduced on DEC printers, and made its first glass appearance on the VT125, though the [http://www.vt100.net/docs/vt3xx-gp/chapter14.html VT3xx] documentation gets the most play (the VT340 appears to have been the first terminal which could sensibly scroll pixel graphics). A single sixel combines a set of programmable color registers with a vertical stack of six pixels; a sixel sprite (sprixel?) is MxN pixels where N is a multiple of 6. It is probably the most widely implemented method of pixel graphics for terminal emulators ([https://sw.kovidgoyal.net/kitty/graphics-protocol.html kitty] has its own protocol, as does [http://www.asmeurer.com/iterm2-tools/images.html ITerm2]). [https://en.wikipedia.org/wiki/ReGIS ReGIS] is a similar method for vector graphics. A single horizontal strip of sixels is a "band"; a sprixel has one or more bands. | Sixel ("six pixels") does not appear to have any true, up-to-date "standard". It seems to have been introduced on DEC printers, and made its first glass appearance on the VT125, though the [http://www.vt100.net/docs/vt3xx-gp/chapter14.html VT3xx] documentation gets the most play (the VT340 appears to have been the first terminal which could sensibly scroll pixel graphics). A single sixel combines a set of programmable color registers with a vertical stack of six pixels; a sixel sprite (sprixel?) is MxN pixels where N is a multiple of 6. It is probably the most widely implemented method of pixel graphics for terminal emulators ([https://sw.kovidgoyal.net/kitty/graphics-protocol.html kitty] has its own protocol, as does [http://www.asmeurer.com/iterm2-tools/images.html ITerm2]). [https://en.wikipedia.org/wiki/ReGIS ReGIS] is a similar method for vector graphics. A single horizontal strip of sixels is a "band"; a sprixel has one or more bands. | ||
Sixels are specified using only printable ASCII characters, and are thus 7-bit clean. | |||
A sprixel must typically be emitted as a single unit to be rendered as a coherent whole (i.e. without gaps between bands). Sprixels do not annihilate entire cells, but only the pixels covered. A glyph emitted atop a sixel will annihilate all pixels contained within the cell. | A sprixel must typically be emitted as a single unit to be rendered as a coherent whole (i.e. without gaps between bands). Sprixels do not annihilate entire cells, but only the pixels covered. A glyph emitted atop a sixel will annihilate all pixels contained within the cell. | ||
==Color registers== | ==Syntax== | ||
Before emitting a sprixel, the terminal must first be put into the appropriate mode via "\e[Pq" ('''FIXME''' details on 8-bit, start params). Properly exit the mode with "\e\\" ('''FIXME''' again 8-bit). | |||
Color registers precede the band data 'en bloc'. Each color register takes the form "#N;T;a;b;c" where N is the register and T is the type (see below). | |||
Bands are separated by hyphens ('-'). Return to the start of a band without moving to the next one (i.e. to draw another color) with '$'. The same number of sixels ought be provided for each color used in a band (but they may of course be the empty sixel). For each sixel, determine which of the six pixels 0..5 (0 on the top, 5 on the bottom) match the color, and and for each pixel N, add 2ⁿ. The result will be between 0 and 63, inclusive. Add 63 to this total; the sixel is the corresponding ASCII character (between 63 and 126, inclusive). When a sixel is repeated four or more times in a row, use "!n" to runlength encode the series. | |||
===Color registers=== | |||
A terminal supports some number of color registers for each sprixel. For <tt>xterm</tt>, this is controlled by the <tt>numColorRegisters</tt> resource (set to a (low) value based off <tt>decTerminalID</tt> if not explicitly provided): | A terminal supports some number of color registers for each sprixel. For <tt>xterm</tt>, this is controlled by the <tt>numColorRegisters</tt> resource (set to a (low) value based off <tt>decTerminalID</tt> if not explicitly provided): | ||
<pre>XTerm*numColorRegisters: 1024</pre> | <pre>XTerm*numColorRegisters: 1024</pre> |
Revision as of 23:36, 1 March 2021
Sixel ("six pixels") does not appear to have any true, up-to-date "standard". It seems to have been introduced on DEC printers, and made its first glass appearance on the VT125, though the VT3xx documentation gets the most play (the VT340 appears to have been the first terminal which could sensibly scroll pixel graphics). A single sixel combines a set of programmable color registers with a vertical stack of six pixels; a sixel sprite (sprixel?) is MxN pixels where N is a multiple of 6. It is probably the most widely implemented method of pixel graphics for terminal emulators (kitty has its own protocol, as does ITerm2). ReGIS is a similar method for vector graphics. A single horizontal strip of sixels is a "band"; a sprixel has one or more bands.
Sixels are specified using only printable ASCII characters, and are thus 7-bit clean.
A sprixel must typically be emitted as a single unit to be rendered as a coherent whole (i.e. without gaps between bands). Sprixels do not annihilate entire cells, but only the pixels covered. A glyph emitted atop a sixel will annihilate all pixels contained within the cell.
Syntax
Before emitting a sprixel, the terminal must first be put into the appropriate mode via "\e[Pq" (FIXME details on 8-bit, start params). Properly exit the mode with "\e\\" (FIXME again 8-bit).
Color registers precede the band data 'en bloc'. Each color register takes the form "#N;T;a;b;c" where N is the register and T is the type (see below).
Bands are separated by hyphens ('-'). Return to the start of a band without moving to the next one (i.e. to draw another color) with '$'. The same number of sixels ought be provided for each color used in a band (but they may of course be the empty sixel). For each sixel, determine which of the six pixels 0..5 (0 on the top, 5 on the bottom) match the color, and and for each pixel N, add 2ⁿ. The result will be between 0 and 63, inclusive. Add 63 to this total; the sixel is the corresponding ASCII character (between 63 and 126, inclusive). When a sixel is repeated four or more times in a row, use "!n" to runlength encode the series.
Color registers
A terminal supports some number of color registers for each sprixel. For xterm, this is controlled by the numColorRegisters resource (set to a (low) value based off decTerminalID if not explicitly provided):
XTerm*numColorRegisters: 1024
Each register is specified with a type ("1" for HSL, "2" for RGB) and three components, each between 0 and 100 inclusive. Assuming 8bpc RGB, every 2.6 bits of component get squashed to 1.
Support
- xterm supports scrolling sprixels when compiled with --enable-sixel-graphics
- and launched with at least a vt340 decGraphicsID (or decTerminalID)
- mlterm works
- alacritty has a patch outstanding to add support, but it is not yet merged as of 0.8.0-dev
- VTE supports sprixels when built with -Dsixel=true
- Microsoft's Windows Terminal is said to support sixel