1notcurses_visual(3)                                        notcurses_visual(3)
2
3
4

NAME

6       notcurses_visual - notcurses multimedia
7

SYNOPSIS

9       #include <notcurses/notcurses.h>
10
11              typedef enum {
12                NCSCALE_NONE,
13                NCSCALE_SCALE,
14                NCSCALE_STRETCH,
15                NCSCALE_NONE_HIRES,
16                NCSCALE_SCALE_HIRES,
17              } ncscale_e;
18
19              typedef enum {
20                NCBLIT_DEFAULT, // let the ncvisual pick
21                NCBLIT_1x1,     // spaces only
22                NCBLIT_2x1,     // halves + 1x1
23                NCBLIT_2x2,     // quadrants + 2x1
24                NCBLIT_3x2,     // sextants + 1x1
25                NCBLIT_BRAILLE, // 4 rows, 2 cols (braille)
26                NCBLIT_PIXEL,   // pixel graphics
27                NCBLIT_4x1,     // four vertical levels, (plots)
28                NCBLIT_8x1,     // eight vertical levels, (plots)
29              } ncblitter_e;
30
31              #define NCVISUAL_OPTION_NODEGRADE     0x0001ull
32              #define NCVISUAL_OPTION_BLEND         0x0002ull
33              #define NCVISUAL_OPTION_HORALIGNED    0x0004ull
34              #define NCVISUAL_OPTION_VERALIGNED    0x0008ull
35              #define NCVISUAL_OPTION_ADDALPHA      0x0010ull
36              #define NCVISUAL_OPTION_CHILDPLANE    0x0020ull
37              #define NCVISUAL_OPTION_NOINTERPOLATE 0x0040ull
38
39              struct ncvisual_options {
40                struct ncplane* n;
41                ncscale_e scaling;
42                int y, x;
43                int begy, begx; // origin of rendered region
44                int leny, lenx; // size of rendered region
45                ncblitter_e blitter; // glyph set to use
46                uint64_t flags; // bitmask over NCVISUAL_OPTION_*
47                uint32_t transcolor; // use this color for ADDALPHA
48                unsigned pxoffy, pxoffx; // pixel offset from origin
49              };
50
51              typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*);
52
53              typedef struct ncvgeom {
54                unsigned pixy, pixx;     // true pixel geometry of ncvisual data
55                unsigned cdimy, cdimx;   // terminal cell geometry when this was calculated
56                unsigned rpixy, rpixx;   // rendered pixel geometry (per visual_options)
57                unsigned rcelly, rcellx; // rendered cell geometry (per visual_options)
58                unsigned scaley, scalex; // pixels per filled cell (scale == c for bitmaps)
59                unsigned begy, begx;     // upper-left corner of used region
60                unsigned leny, lenx;     // geometry of used region
61                unsigned maxpixely, maxpixelx; // only defined for NCBLIT_PIXEL
62                ncblitter_e blitter;i    // blitter that will be used
63              } ncvgeom;
64
65       struct ncvisual* ncvisual_from_file(const char* file);
66
67       struct  ncvisual*  ncvisual_from_rgba(const  void*  rgba, int rows, int
68       rowstride, int cols);
69
70       struct ncvisual* ncvisual_from_rgb_packed(const void* rgba,  int  rows,
71       int rowstride, int cols, int alpha);
72
73       struct  ncvisual*  ncvisual_from_rgb_loose(const  void* rgba, int rows,
74       int rowstride, int cols, int alpha);
75
76       struct ncvisual* ncvisual_from_bgra(const void*  bgra,  int  rows,  int
77       rowstride, int cols);
78
79       struct  ncvisual*  ncvisual_from_palidx(const void* data, int rows, int
80       rowstride, int cols, int palsize, int  pstride,  const  uint32_t*  pal‐
81       ette);
82
83       struct  ncvisual*  ncvisual_from_plane(struct  ncplane*  n, ncblitter_e
84       blit, unsigned begy, unsigned begx, unsigned leny, unsigned lenx);
85
86       int ncvisual_geom(const struct notcurses* nc, const struct ncvisual* n,
87       const struct ncvisual_options* vopts, ncvgeom* geom);
88
89       void ncvisual_destroy(struct ncvisual* ncv);
90
91       int ncvisual_decode(struct ncvisual* ncv);
92
93       int ncvisual_decode_loop(struct ncvisual* ncv);
94
95       struct  ncplane*  ncvisual_blit(struct  notcurses* nc, struct ncvisual*
96       ncv, const struct ncvisual_options* vopts);
97
98       static inline struct  ncplane*  ncvisualplane_create(struct  notcurses*
99       nc,  const  struct  ncplane_options* opts, struct ncvisual* ncv, struct
100       ncvisual_options* vopts);
101
102       int ncvisual_simple_streamer(struct ncplane* n, struct  ncvisual*  ncv,
103       const struct timespec* disptime, void* curry);
104
105       int  ncvisual_stream(struct  notcurses* nc, struct ncvisual* ncv, float
106       timescale, streamcb streamer,  const  struct  ncvisual_options*  vopts,
107       void* curry);
108
109       int ncvisual_rotate(struct ncvisual* n, double rads);
110
111       int ncvisual_resize(struct ncvisual* n, int rows, int cols);
112
113       int  ncvisual_resize_noninterpolative(struct ncvisual* n, int rows, int
114       cols);
115
116       int ncvisual_polyfill_yx(struct ncvisual* n, int y, int x, uint32_t rg‐
117       ba);
118
119       int  ncvisual_at_yx(const  struct  ncvisual* n, unsigned y, unsigned x,
120       uint32_t* pixel);
121
122       int ncvisual_set_yx(const struct ncvisual* n, unsigned y,  unsigned  x,
123       uint32_t pixel);
124
125       struct  ncplane*  ncvisual_subtitle_plane(struct ncplane* parent, const
126       struct ncvisual* ncv);
127
128       int notcurses_lex_scalemode(const char* op, ncscale_e* scaling);
129
130       const char* notcurses_str_scalemode(ncscale_e scaling);
131
132       int notcurses_lex_blitter(const char* op, ncblitter_e* blitter);
133
134       const char* notcurses_str_blitter(ncblitter_e blitter);
135
136       ncblitter_e ncvisual_media_defblitter(const struct  notcurses  nc,  nc‐
137       scale_e scaling);
138
139       int  ncplane_qrcode(struct  ncplane* n, unsigned* ymax, unsigned* xmax,
140       const void* data, size_t len)
141
142       struct ncvisual* ncvisual_from_sixel(const char* s, unsigned leny,  un‐
143       signed lenx);
144

DESCRIPTION

146       An  ncvisual  is a virtual pixel framebuffer.  They can be created from
147       RGBA/BGRA data in  memory  (ncvisual_from_rgba/ncvisual_from_bgra),  or
148       from  the  content  of  a suitable ncplane (ncvisual_from_ncplane).  If
149       Notcurses was built against a  multimedia  engine  (FFMpeg  or  OpenIm‐
150       ageIO),  image and video files can be loaded into visuals using ncvisu‐
151       al_from_file.  ncvisual_from_file discovers the container  and  codecs,
152       but  does not verify that the entire file is well-formed.  ncvisual_de‐
153       code ought be invoked to recover subsequent  frames,  once  per  frame.
154       ncvisual_decode_loop will return to the first frame, as if ncvisual_de‐
155       code had never been called.
156
157       Once the visual is loaded, it can be transformed using ncvisual_rotate,
158       ncvisual_resize,  and ncvisual_resize_noninterpolative.  These are per‐
159       sistent operations, unlike any scaling that takes place at render time.
160       If  a  subtitle  is  associated with the frame, it can be acquired with
161       ncvisual_subtitle_plane.  ncvisual_resize uses the media  layer's  best
162       scheme to enlarge or shrink the original data, typically involving some
163       interpolation.  ncvisual_resize_noninterpolative performs a naive  lin‐
164       ear sampling, retaining only original colors.
165
166       ncvisual_from_rgba  and  ncvisual_from_bgra  both  require  a number of
167       rows, a number of image columns cols, and a virtual row length of  row‐
168       stride / 4 columns.  The input data must provide 32 bits per pixel, and
169       thus must be at least rowstride * rows bytes, of which a cols * rows  *
170       4-byte subset is used.  It is not possible to mmap(2) an image file and
171       use it directly--decompressed, decoded data is necessary.  The  result‐
172       ing plane will be ceil(rows/2) rows, and cols columns.
173
174       ncvisual_from_rgb_packed  performs the same using 3-byte RGB source da‐
175       ta.  ncvisual_from_rgb_loose uses 4-byte RGBx source data.   Both  will
176       fill  in  the  alpha component of every target pixel with the specified
177       alpha.
178
179       ncvisual_from_palidx requires a palette of at least palsize ncchannels.
180       Pixels  are  pstride  bytes each, arranged as cols pixels per row, with
181       each row occupying rowstride bytes, across rows rows.
182
183       ncvisual_from_plane requires specification of  a  rectangle  via  begy,
184       begx, leny, and lenx, and also a blitter.  The only valid glyphs within
185       this region are those used by the specified blitter.
186
187       ncvisual_rotate executes a rotation of rads radians, in  the  clockwise
188       (positive) or counterclockwise (negative) direction.
189
190       ncvisual_subtitle_plane  returns a struct ncplane suitable for display,
191       if the current frame had such a subtitle.  Note that the same  subtitle
192       might  be  returned  for multiple frames, or might not.  It is atypical
193       for all frames to have subtitles.  Subtitles can be text or graphics.
194
195       ncvisual_blit draws the visual to an ncplane, based on the contents  of
196       its  struct ncvisual_options.  If n is not NULL, it specifies the plane
197       on which to render, and y/x specify a location within that plane.  Oth‐
198       erwise,  a new plane will be created, and placed at y/x relative to the
199       rendering area.  begy/begx specify the upper left corner of a subregion
200       of  the  ncvisual  to  render,  while leny/lenx specify the geometry of
201       same.  flags is a bitfield over:
202
203NCVISUAL_OPTION_NODEGRADE If the specified blitter is not  available,
204         fail rather than degrading.
205
206NCVISUAL_OPTION_BLEND: Render with NCALPHA_BLEND.  Not available with
207         NCBLIT_PIXEL when using Sixel graphics.  When used with  NCBLIT_PIXEL
208         when using Kitty graphics, the alpha channel is divided by 2 for each
209         pixel.
210
211NCVISUAL_OPTION_HORALIGNED: Interpret x as an ncalign_e.
212
213NCVISUAL_OPTION_VERALIGNED: Interpret y as an ncalign_e.
214
215NCVISUAL_OPTION_ADDALPHA: Interpret the lower 24 bits  of  transcolor
216         as a transparent color.
217
218NCVISUAL_OPTION_CHILDPLANE: Make a new plane, as a child of n.
219
220       ncvisual_geom allows the caller to determine any or all of the visual's
221       pixel geometry, the blitter to be used, and that blitter's  scaling  in
222       both  dimensions.   Any  but  the final argument may be NULL, though at
223       least one of nc and n must be non-NULL.  If nc is NULL, only properties
224       intrinsic  to  the visual are returned (i.e.  its original pixel geome‐
225       try).  If n is NULL, only properties independent of the visual are  re‐
226       turned  (i.e.   cell-pixel  geometry  and maximum bitmap geometry).  If
227       both are supplied, all fields of the ncvgeom structure are filled in.
228
229       ncplane_qrcode draws an ISO/IEC 18004:2015 QR Code for the len bytes of
230       data  using NCBLIT_2x1 (this is the only blitter that will work with QR
231       Code scanners, due to its 1:1 aspect ratio).
232

OPTIONS

234       begy and begx specify the upper left corner of the image to start draw‐
235       ing.   leny  and  lenx  specify  the  area of the subimage drawn.  leny
236       and/or lenx may be specified as a negative number to draw  through  the
237       bottom right corner of the image.
238
239       The  n  field specifies the plane to use.  If this is NULL, a new plane
240       will be created, having the precise  geometry  necessary  to  blit  the
241       specified  region of the image.  This might be larger (or smaller) than
242       the visual area.
243
244       y and x have different meanings depending on whether or not n is  NULL.
245       If  not  (drawing  onto a preexisting plane), they specify where in the
246       plane to start drawing.  If n was NULL (new plane),  they  specify  the
247       origin  of  the  new  plane relative to the visible area.  If the flags
248       field contains NCVISUAL_OPTION_HORALIGNED, the x  parameter  is  inter‐
249       preted  as an ncalign_e rather than an absolute position.  If the flags
250       field contains NCVISUAL_OPTION_VERALIGNED, the y  parameter  is  inter‐
251       preted  as an ncalign_e rather than an absolute position.  If the flags
252       field contains NCVISUAL_OPTION_CHILDPLANE, n must be non-NULL, and  the
253       x and y parameters are interpreted relative to that plane.
254

BLITTERS

256       The  different  ncblitter_e  values  select  from among available glyph
257       sets:
258
259NCBLIT_DEFAULT: Let the ncvisual choose its own blitter.
260
261NCBLIT_1x1: Spaces only.  Works in ASCII, unlike most other blitters.
262
263NCBLIT_2x1: Adds the half blocks (▄▀) to NCBLIT_1x1.
264
265NCBLIT_2x2: Adds left and right half blocks (▌▐) and quadrants (▖▗▟▙)
266         to NCBLIT_2x1.
267
268NCBLIT_3x2: Adds sextants to NCBLIT_1x1.
269
270NCBLIT_BRAILLE:     4    rows    and    2    columns    of    braille
271         (⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿).
272
273NCBLIT_PIXEL: Adds pixel graphics (these also work in ASCII).
274
275       Two more blitters exist for plots, but are unsuitable for  generic  me‐
276       dia:
277
278NCBLIT_4x1: Adds ¼ and ¾ blocks (▂▆) to NCBLIT_2x1.
279
280NCBLIT_8x1: Adds ⅛, ⅜, ⅝, and ⅞ blocks (▇▅▃▁) to NCBLIT_4x1.
281
282       NCBLIT_4x1  and NCBLIT_8x1 are intended for use with plots, and are not
283       really applicable for general visuals.  NCBLIT_BRAILLE doesn't tend  to
284       work  out very well for images, but (depending on the font) can be very
285       good for plots.
286
287       A string can be transformed to a  blitter  with  notcurses_lex_blitter,
288       recognizing  ascii,  half, quad, sex, fourstep, braille, eightstep, and
289       pixel.  Conversion in the opposite direction is performed with notcurs‐
290       es_str_blitter.
291
292       In  the  absence  of  scaling, for a given set of pixels, more rows and
293       columns in the blitter will result in a smaller output image.  An image
294       rendered  with  NCBLIT_1x1 will be twice as tall as the same image ren‐
295       dered with NCBLIT_2x1, which will be twice as wide as  the  same  image
296       rendered with NCBLIT_2x2.  The same image rendered with NCBLIT_3x2 will
297       be one-third as tall and one-half as wide as  the  original  NCBLIT_1x1
298       render  (again,  this  depends on NCSCALE_NONE).  If the output size is
299       held constant (using for instance NCSCALE_SCALE_HIRES and a  large  im‐
300       age), more rows and columns will result in more effective resolution.
301
302       A string can be transformed to a scaling mode with notcurses_lex_scale‐
303       mode, recognizing stretch, scalehi, hires, scale, and none.  Conversion
304       in the opposite direction is performed with notcurses_str_scalemode.
305
306       Assuming  a cell is twice as tall as it is wide, NCBLIT_1x1 (and indeed
307       any NxN blitter) will stretch an image by a factor of 2 in the vertical
308       dimension.   NCBLIT_2x1  will  not  distort the image whatsoever, as it
309       maps a vector two pixels high and one pixel  wide  to  a  single  cell.
310       NCBLIT_3x2 will stretch an image by a factor of 1.5.
311
312       The cell's dimension in pixels is ideally evenly divisible by the blit‐
313       ter geometry.  If NCBLIT_3x2 is used together with a cell 8 pixels wide
314       and 14 pixels tall, two of the vertical segments will be 5 pixels tall,
315       while one will be 4 pixels tall.  Such unequal distributions  are  more
316       likely  with  larger blitter geometries.  Likewise, there are only ever
317       two colors available to us in a given cell.  NCBLIT_1x1 and  NCBLIT_2x2
318       can  be  perfectly  represented  with two colors per cell.  Blitters of
319       higher geometry are increasingly likely to require some degree  of  in‐
320       terpolation.  Transparency is always honored with complete fidelity.
321
322       Finally,  rendering  operates slightly differently when two planes have
323       both been blitted, and one lies atop  the  other.   See  notcurses_ren‐
324       der(3) for more information.
325

PIXEL BLITTING

327       Some terminals support pixel-based output via one of a number of proto‐
328       cols.  NCBLIT_PIXEL has some stringent  requirements  on  the  type  of
329       planes  it  can  be  used with; it is usually best to let ncvisual_blit
330       create the backing plane by providing a NULL value for n.  If you  must
331       bring  your  own plane, it must be perfectly sized for the bitmap (i.e.
332       large enough, and not more than a full cell  larger  in  either  dimen‐
333       sion--the  bitmap, always placed at the origin, must at least partially
334       cover every cell of the plane).  Using NCSCALE_STRETCH means  that  the
335       second  condition  will  always be met.  Once a sprixel is blitted to a
336       plane, cell methods (including cell blitting) may not be used with  it.
337       Resizing  the  plane  eliminates  the  sprixel,  as does destroying the
338       plane.  A sprixelated plane may be moved in all three  dimensions,  du‐
339       plicated,  and  reparented.   The  base  cell of a sprixelated plane is
340       meaningless; if the sprixel is not an even multiple of the cell  geome‐
341       try, any excess cell material is ignored during rendering.
342
343       Only  one  bitmap  can  be blitted onto a plane at a time (but multiple
344       planes with bitmaps may be visible); blitting  a  second  to  the  same
345       plane will delete the original.
346
347       pxoffy  and  pxoffx  can specify an offset from the origin of the upper
348       left cell.  This can be used for absolute positioning of a  bitmap,  or
349       for smooth movement of same.  It is an error if pxoffy exceeds the cell
350       height in pixels, or pxoffx exceeds  the  cell  width  in  pixels.   If
351       NCBLIT_PIXEL is not used, these fields are ignored.
352

RETURN VALUES

354       ncvisual_from_file  returns  an  ncvisual object on success, or NULL on
355       failure.  Success indicates that the specified  file  was  opened,  and
356       enough  data was read to make a firm codec identification.  It does not
357       imply that the entire file is properly-formed.
358
359       ncvisual_decode returns 0 on success, or 1 on end of  file,  or  -1  on
360       failure.   It  is  only necessary for multimedia-based visuals.  It ad‐
361       vances one frame for each call.  ncvisual_decode_loop has the same  re‐
362       turn  values: when called following decoding of the last frame, it will
363       return 1, but a subsequent ncvisual_blit will return the first frame.
364
365       ncvisual_from_plane returns NULL if the ncvisual cannot be created  and
366       bound.  This is usually due to illegal content in the source ncplane.
367
368       ncvisual_blit  returns  NULL on error, and otherwise the plane to which
369       the visual was rendered.  If opts->n is provided, this will be opts->n.
370       Otherwise,  a plane will be created, perfectly sized for the visual and
371       the specified blitter.
372
373       ncvisual_geom returns non-zero if the specified  configuration  is  in‐
374       valid, or if both nc and n are NULL.
375
376       ncvisual_media_defblitter  returns  the  blitter selected by NCBLIT_DE‐
377       FAULT in the specified configuration.  If UTF8  is  not  enabled,  this
378       will  always be NCBLIT_1x1.  If scale is NCSCALE_NONE or NCSCALE_SCALE,
379       the aspect-preserving NCBLIT_2x1 will be  returned.   If  sextants  are
380       available  (see notcurses_cansextant), this will be NCBLIT_3x2, or oth‐
381       erwise NCBLIT_2x2.
382

NOTES

384       Multimedia decoding requires that Notcurses be built with either FFmpeg
385       or  OpenImageIO support.  What formats can be decoded is totally depen‐
386       dent on the linked library.  OpenImageIO does  not  support  subtitles.
387       Functions requiring a multimedia backend include ncvisual_from_file and
388       ncvisual_subtitle_plane.
389
390       Sixel  documentation  can   be   found   at   Dankwiki   (https://nick-
391       black.com/dankwiki/index.php?title=Sixel).   Kitty's  graphics protocol
392       is  specified  in  its  documentation   (https://sw.kovidgoyal.net/kit
393       ty/graphics-protocol.html).
394
395       Bad   font   support   can  ruin  NCBLIT_2x2,  NCBLIT_3x2,  NCBLIT_4x1,
396       NCBLIT_BRAILLE, and NCBLIT_8x1.  Braille glyphs ought ideally draw only
397       the  raised dots, rather than drawing all eight dots with two different
398       styles.  It's often best for the emulator to draw these glyphs itself.
399
400       Several emulators claim to implement Sixel, but do so in a more or less
401       broken fashion.  I consider XTerm and foot to be reference Sixel imple‐
402       mentations on X.org and Wayland, respectively.
403
404       Sixels are fundamentally expressed in terms of six-line bands.  If  the
405       rendered  bitmap is not a multiple of six rows, the necessary rows will
406       be faked via transparent rows.  All sprixels have a height in rows, and
407       if  this  height is not a multiple of the cell height in rows, the last
408       rows will only partially obstruct a row of cells.  This can lead to un‐
409       desirable  redraws  and  flicker  if  the  cells underneath the sprixel
410       change.  A sprixel which is both a multiple of the cell  height  and  a
411       multiple of six is the most predictable possible sprixel.
412
413       When  using  non-interpolative  blitting  together with scaling, unless
414       your goal includes minimizing the total area required, lower-resolution
415       blitters  will  generally  look just as good as higher resolution blit‐
416       ters, and be faster.
417
418       The results of ncvisual_geom are invalidated by a terminal resize.
419

BUGS

421       Functions which describe  rendered  state  such  as  ncplane_at_yx  and
422       notcurses_at_yx  will  return  an  nccell  with  a sprixel ID, but this
423       sprixel cannot be accessed.
424
425       ncvisual_rotate currently supports only M_PI/2 and -M_PI/2 radians  for
426       rads, but this will change soon.
427
428       ncvisual_blit  should  be able to create new planes in piles other than
429       the standard pile.  This ought become a reality soon.
430
431       ncvisual_stream currently requires a multimedia engine, which is silly.
432       This will change in the near future.
433
434       Sprixels  interact  poorly with multiple planes, and such usage is dis‐
435       couraged.  This situation might improve in the future.
436
437       Multiple threads may not currently call ncvisual_blit concurrently  us‐
438       ing  the same ncvisual, even if targeting distinct ncplanes.  This will
439       likely change in the future.
440
441       pxoffy and pxoffx are not yet implemented.
442

SEE ALSO

444       notcurses(3), notcurses_capabilities(3),  notcurses_plane(3),  notcurs‐
445       es_render(3), utf-8(7)
446

AUTHORS

448       nick black <nickblack@linux.com>.
449
450
451
452                                    v3.0.8                 notcurses_visual(3)
Impressum