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_INFLATE,
18              } ncscale_e;
19
20              typedef enum {
21                NCBLIT_DEFAULT, // let the ncvisual pick
22                NCBLIT_1x1,     // spaces only
23                NCBLIT_2x1,     // halves + 1x1
24                NCBLIT_2x2,     // quadrants + 2x1
25                NCBLIT_3x2,     // sextants + 1x1
26                NCBLIT_BRAILLE, // 4 rows, 2 cols (braille)
27                NCBLIT_PIXEL,   // pixel graphics
28                NCBLIT_4x1,     // four vertical levels, (plots)
29                NCBLIT_8x1,     // eight vertical levels, (plots)
30              } ncblitter_e;
31
32              #define NCVISUAL_OPTION_NODEGRADE  0x0001
33              #define NCVISUAL_OPTION_BLEND      0x0002
34              #define NCVISUAL_OPTION_HORALIGNED 0x0004
35              #define NCVISUAL_OPTION_VERALIGNED 0x0008
36              #define NCVISUAL_OPTION_ADDALPHA   0x0010
37              #define NCVISUAL_OPTION_CHILDPLANE 0x0020
38
39              struct ncvisual_options {
40                struct ncplane* n;
41                ncscale_e scaling;
42                int y, x;
43                int begy, begx; // origin of rendered section
44                int leny, lenx; // size of rendered section
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              };
49
50              typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*);
51
52       struct ncvisual* ncvisual_from_file(const char* file);
53
54       struct  ncvisual*  ncvisual_from_rgba(const  void*  rgba, int rows, int
55       rowstride, int cols);
56
57       struct ncvisual* ncvisual_from_bgra(const void*  bgra,  int  rows,  int
58       rowstride, int cols);
59
60       struct  ncvisual*  ncvisual_from_plane(struct  ncplane*  n, ncblitter_e
61       blit, int begy, int begx, int leny, int lenx);
62
63       int ncvisual_blitter_geom(const  struct  notcurses*  nc,  const  struct
64       ncvisual* n, const struct ncvisual_options* vopts, int* y, int* x, int*
65       scaley, int* scalex, ncblitter_e* blitter);
66
67       void ncvisual_destroy(struct ncvisual* ncv);
68
69       int ncvisual_decode(struct ncvisual* ncv);
70
71       int ncvisual_decode_loop(struct ncvisual* ncv);
72
73       struct ncplane* ncvisual_render(struct notcurses* nc, struct  ncvisual*
74       ncv, const struct ncvisual_options* vopts);
75
76       int  ncvisual_simple_streamer(struct  ncplane* n, struct ncvisual* ncv,
77       const struct timespec* disptime, void* curry);
78
79       int ncvisual_stream(struct notcurses* nc, struct ncvisual*  ncv,  float
80       timescale,  streamcb  streamer,  const  struct ncvisual_options* vopts,
81       void* curry);
82
83       int ncvisual_rotate(struct ncvisual* n, double rads);
84
85       int ncvisual_resize(struct ncvisual* n, int rows, int cols);
86
87       int ncvisual_inflate(struct ncvisual* n, int scale);
88
89       int ncvisual_polyfill_yx(struct ncvisual* n, int y, int x, uint32_t rg‐
90       ba);
91
92       int  ncvisual_at_yx(const  struct  ncvisual* n, int y, int x, uint32_t*
93       pixel);
94
95       int ncvisual_set_yx(const struct ncvisual* n, int y,  int  x,  uint32_t
96       pixel);
97
98       char* ncvisual_subtitle(const struct ncvisual* ncv);
99
100       int notcurses_lex_scalemode(const char* op, ncscale_e* scaling);
101
102       const char* notcurses_str_scalemode(ncscale_e scaling);
103
104       int notcurses_lex_blitter(const char* op, ncblitter_e* blitter);
105
106       const char* notcurses_str_blitter(ncblitter_e blitter);
107
108       ncblitter_e  ncvisual_media_defblitter(const  struct  notcurses nc, nc‐
109       scale_e scaling);
110
111       int ncplane_qrcode(struct ncplane* n, int* ymax, int* xmax, const void*
112       data, size_t len)
113

DESCRIPTION

115       An  ncvisual  is a virtual pixel framebuffer.  They can be created from
116       RGBA/BGRA data in  memory  (ncvisual_from_rgba/ncvisual_from_bgra),  or
117       from  the  content  of  a suitable ncplane (ncvisual_from_ncplane).  If
118       Notcurses was built against a  multimedia  engine  (FFMpeg  or  OpenIm‐
119       ageIO),  image and video files can be loaded into visuals using ncvisu‐
120       al_from_file.  ncvisual_from_file discovers the container  and  codecs,
121       but  does not verify that the entire file is well-formed.  ncvisual_de‐
122       code ought be invoked to recover subsequent  frames,  once  per  frame.
123       ncvisual_decode_loop will return to the first frame, as if ncvisual_de‐
124       code had never been called.
125
126       Once the visual is loaded, it can be transformed using ncvisual_rotate,
127       ncvisual_resize,  and  ncvisual_inflate.   These  are persistent opera‐
128       tions, unlike any scaling that takes place at render time.  If a subti‐
129       tle is associated with the frame, it can be acquired with ncvisual_sub‐
130       title.  ncvisual_resize uses the media layer's best scheme  to  enlarge
131       or  shrink  the  original data, typically involving some interpolation.
132       ncvisual_inflate maps each pixel to scalexscale pixels square,  retain‐
133       ing the original color; it is an error if scale is less than one.
134
135       ncvisual_from_rgba  and  ncvisual_from_bgra  both  require  a number of
136       rows, a number of image columns cols, and a virtual row length of  row‐
137       stride / 4 columns.  The input data must provide 32 bits per pixel, and
138       thus must be at least rowstride * rows bytes, of which a cols * rows  *
139       4-byte subset is used.  It is not possible to mmap(2) an image file and
140       use it directly--decompressed, decoded data is necessary.  The  result‐
141       ing  plane  will  be  ceil(rows/2)  rows,  and  cols  columns.  ncvisu‐
142       al_from_plane requires specification of a rectangle via begy, begx, le‐
143       ny,  and  lenx.  The only valid characters within this region are those
144       used by the NCBLIT_2x2 blitter, though this may change in the future.
145
146       ncvisual_rotate executes a rotation of rads radians, in  the  clockwise
147       (positive) or counterclockwise (negative) direction.
148
149       ncvisual_subtitle will return a UTF-8-encoded subtitle corresponding to
150       the current frame if such a subtitle was decoded.  Note that a subtitle
151       might be returned for multiple frames, or might not.
152
153       ncvisual_render  blits  the visual to an ncplane, based on the contents
154       of its struct ncvisual_options.  If n is not  NULL,  it  specifies  the
155       plane on which to render, and y/x specify a location within that plane.
156       Otherwise, a new plane will be created, and placed at y/x  relative  to
157       the  rendering area.  begy/begx specify the upper left corner of a sub‐
158       section of the ncvisual to render, while leny/lenx specify the geometry
159       of same.  flags is a bitfield over:
160
161NCVISUAL_OPTION_NODEGRADE  If the specified blitter is not available,
162         fail rather than degrading.
163
164NCVISUAL_OPTION_BLEND: Render with CELL_ALPHA_BLEND.
165
166NCVISUAL_OPTION_HORALIGNED: Interpret x as an ncalign_e.
167
168NCVISUAL_OPTION_VERALIGNED: Interpret y as an ncalign_e.
169
170NCVISUAL_OPTION_ADDALPHA: Interpret the lower 24 bits  of  transcolor
171         as a transparent color.
172
173NCVISUAL_OPTION_CHILDPLANE: Make a new plane, as a child of n.
174
175       ncvisual_blitter_geom  allows the caller to determine any or all of the
176       visual's pixel geometry, the blitter to be  used,  and  that  blitter's
177       scaling in both dimensions.  Any but the first argument may be NULL.
178
179       ncplane_qrcode draws an ISO/IEC 18004:2015 QR Code for the len bytes of
180       data using NCBLIT_2x1 (this is the only blitter that will work with  QR
181       Code scanners, due to its 1:1 aspect ratio).
182

OPTIONS

184       begy and begx specify the upper left corner of the image to start draw‐
185       ing.  leny and lenx specify the  area  of  the  subimage  drawn.   leny
186       and/or  lenx  may be specified as a negative number to draw through the
187       bottom right corner of the image.
188
189       The n field specifies the plane to use.  If this is NULL, a  new  plane
190       will  be  created,  having  the  precise geometry necessary to blit the
191       specified section of the image.  This might be larger (or smaller) than
192       the visual area.
193
194       y  and x have different meanings depending on whether or not n is NULL.
195       If not (drawing onto a preexisting plane), they specify  where  in  the
196       plane  to  start  drawing.  If n was NULL (new plane), they specify the
197       origin of the new plane relative to the standard plane.  If  the  flags
198       field  contains  NCVISUAL_OPTION_HORALIGNED,  the x parameter is inter‐
199       preted as an ncalign_e rather than an absolute position.  If the  flags
200       field  contains  NCVISUAL_OPTION_VERALIGNED,  the y parameter is inter‐
201       preted as an ncalign_e rather than an absolute position.  If the  flags
202       field  contains NCVISUAL_OPTION_CHILDPLANE, n must be non-NULL, and the
203       x and y parameters are interpreted relative to that plane.
204

BLITTERS

206       The different ncblitter_e values  select  from  among  available  glyph
207       sets:
208
209NCBLIT_DEFAULT: Let the ncvisual choose its own blitter.
210
211NCBLIT_1x1: Spaces only.  Works in ASCII, unlike most other blitters.
212
213NCBLIT_2x1: Adds the half blocks (▄▀) to NCBLIT_1x1.
214
215NCBLIT_2x2: Adds left and right half blocks (▌▐) and quadrants (▖▗▟▙)
216         to NCBLIT_2x1.
217
218NCBLIT_3x2: Adds sextants to NCBLIT_1x1.
219
220NCBLIT_BRAILLE:    4    rows    and    2    columns    of     braille
221         (⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿).
222
223NCBLIT_PIXEL: Adds pixel graphics (these also work in ASCII).
224
225       Two  more  blitters exist for plots, but are unsuitable for generic me‐
226       dia:
227
228NCBLIT_4x1: Adds ¼ and ¾ blocks (▂▆) to NCBLIT_2x1.
229
230NCBLIT_8x1: Adds ⅛, ⅜, ⅝, and ⅞ blocks (▇▅▃▁) to NCBLIT_4x1.
231
232       NCBLIT_4x1 and NCBLIT_8x1 are intended for use with plots, and are  not
233       really  applicable for general visuals.  NCBLIT_BRAILLE doesn't tend to
234       work out very well for images, but (depending on the font) can be  very
235       good for plots.
236
237       A  string  can  be transformed to a blitter with notcurses_lex_blitter,
238       recognizing ascii, half, quad, sex, fourstep, braille,  eightstep,  and
239       pixel.  Conversion in the opposite direction is performed with notcurs‐
240       es_str_blitter.
241
242       In the absence of scaling, for a given set of  pixels,  more  rows  and
243       columns in the blitter will result in a smaller output image.  An image
244       rendered with NCBLIT_1x1 will be twice as tall as the same  image  ren‐
245       dered  with  NCBLIT_2x1,  which will be twice as wide as the same image
246       rendered with NCBLIT_2x2.  The same image rendered with NCBLIT_3x2 will
247       be  one-third  as  tall and one-half as wide as the original NCBLIT_1x1
248       render (again, this depends on NCSCALE_NONE).  If the  output  size  is
249       held  constant  (using for instance NCSCALE_SCALE_HIRES and a large im‐
250       age), more rows and columns will result in more effective resolution.
251
252       A string can be transformed to a scaling mode with notcurses_lex_scale‐
253       mode,  recognizing  stretch,  scalehi, hires, scale, inflate, and none.
254       Conversion  in  the  opposite  direction  is  performed  with  notcurs‐
255       es_str_scalemode.
256
257       Assuming  a cell is twice as tall as it is wide, NCBLIT_1x1 (and indeed
258       any NxN blitter) will stretch an image by a factor of 2 in the vertical
259       dimension.   NCBLIT_2x1  will  not  distort the image whatsoever, as it
260       maps a vector two pixels high and one pixel  wide  to  a  single  cell.
261       NCBLIT_3x2 will stretch an image by a factor of 1.5.
262
263       The cell's dimension in pixels is ideally evenly divisible by the blit‐
264       ter geometry.  If NCBLIT_3x2 is used together with a cell 8 pixels wide
265       and 14 pixels tall, two of the vertical segments will be 5 pixels tall,
266       while one will be 4 pixels tall.  Such unequal distributions  are  more
267       likely  with  larger blitter geometries.  Likewise, there are only ever
268       two colors available to us in a given cell.  NCBLIT_1x1 and  NCBLIT_2x2
269       can  be  perfectly  represented  with two colors per cell.  Blitters of
270       higher geometry are increasingly likely to require some degree  of  in‐
271       terpolation.  Transparency is always honored with complete fidelity.
272
273       Finally,  rendering  operates slightly differently when two planes have
274       both been blitted, and one lies atop  the  other.   See  notcurses_ren‐
275       der(3) for more information.
276

PIXEL BLITTING

278       Some terminals support pixel-based output via one of a number of proto‐
279       cols.  Checking for bitmap support requires interrogating the  terminal
280       and  reading  a  response.  This takes time, and will never complete if
281       the terminal doesn't respond.  Notcurses will not do so without an  ex‐
282       plicit  request from the client code.  Before NCBLIT_PIXEL can be used,
283       it is thus necessary to call  notcurses_check_pixel_support.   If  this
284       function  has  not  successfully returned, attempts to use NCBLIT_PIXEL
285       will fall  back  to  cell-based  blitting  (or  fail,  if  NCVISUAL_OP‐
286       TION_NODEGRADE is used).
287
288       NCBLIT_PIXEL  has  some stringent requirements on the type of planes it
289       can be used with; it is usually best to let ncvisual_render create  the
290       backing  plane by providing a NULL value for n.  If you must bring your
291       own plane, it must be perfectly  sized  for  the  bitmap  (i.e.   large
292       enough,  and  not more than a full cell larger in either dimension--the
293       bitmap, always placed at the origin, must at least partially cover  ev‐
294       ery  cell  of  the plane).  Using NCSCALE_STRETCH means that the second
295       condition will always be met.  Once a sprixel is blitted  to  a  plane,
296       cell methods (including cell blitting) may not be used with it.  Resiz‐
297       ing the plane eliminates the sprixel, as does destroying the plane.   A
298       sprixelated plane may be moved in all three dimensions, duplicated, and
299       reparented.  The base cell of a sprixelated plane  is  meaningless;  if
300       the  sprixel  is  not an even multiple of the cell geometry, any excess
301       cell material is ignored during rendering.
302
303       Only one bitmap can be blitted onto a plane at  a  time  (but  multiple
304       planes  with  bitmaps  may  be  visible); blitting a second to the same
305       plane will delete the original.
306

RETURN VALUES

308       ncvisual_from_file returns an ncvisual object on success,  or  NULL  on
309       failure.   Success  indicates  that  the specified file was opened, and
310       enough data was read to make a firm codec identification.  It does  not
311       imply that the entire file is properly-formed.
312
313       ncvisual_decode  returns  0  on  success, or 1 on end of file, or -1 on
314       failure.  It is only necessary for multimedia-based  visuals.   It  ad‐
315       vances  one frame for each call.  ncvisual_decode_loop has the same re‐
316       turn values: when called following decoding of the last frame, it  will
317       return 1, but a subsequent ncvisual_render will return the first frame.
318
319       ncvisual_from_plane  returns NULL if the ncvisual cannot be created and
320       bound.  This is usually due to illegal content in the source ncplane.
321
322       ncvisual_render returns NULL on error, and otherwise the plane to which
323       the visual was rendered.  If opts->n is provided, this will be opts->n.
324       Otherwise, a plane will be created, perfectly sized for the visual  and
325       the specified blitter.
326
327       ncvisual_blitter_geom  returns non-zero if the specified blitter is in‐
328       valid.
329
330       ncvisual_media_defblitter returns the blitter  selected  by  NCBLIT_DE‐
331       FAULT  in  the  specified  configuration.  If UTF8 is not enabled, this
332       will always be NCBLIT_1x1.  If scale is NCSCALE_NONE or  NCSCALE_SCALE,
333       the  aspect-preserving  NCBLIT_2x1  will  be returned.  If sextants are
334       available (see notcurses_cansextant), this will be NCBLIT_3x2, or  oth‐
335       erwise NCBLIT_2x2.
336

NOTES

338       Multimedia decoding requires that Notcurses be built with either FFmpeg
339       or OpenImageIO support.  What formats can be decoded is totally  depen‐
340       dent on the linked library.  OpenImageIO does not support subtitles.
341
342       Sixel   documentation   can   be   found   at  Dankwiki  (https://nick-
343       black.com/dankwiki/index.php?title=Sixel).  Kitty's  graphics  protocol
344       is   specified  in  its  documentation  (https://sw.kovidgoyal.net/kit
345       ty/graphics-protocol.html).
346
347       Bad  font  support  can  ruin   NCBLIT_2x2,   NCBLIT_3x2,   NCBLIT_4x1,
348       NCBLIT_BRAILLE, and NCBLIT_8x1.  Braille glyphs ought ideally draw only
349       the raised dots, rather than drawing all eight dots with two  different
350       styles.  It's often best for the emulator to draw these glyphs itself.
351
352       Several emulators claim to implement Sixel, but do so in a more or less
353       broken fashion.  I consider XTerm and foot to be reference Sixel imple‐
354       mentations on X.org and Wayland, respectively.
355
356       Sixels  are fundamentally expressed in terms of six-line bands.  If the
357       rendered bitmap is not a multiple of six rows, the necessary rows  will
358       be faked via transparent rows.  All sprixels have a height in rows, and
359       if this height is not a multiple of the cell height in rows,  the  last
360       rows will only partially obstruct a row of cells.  This can lead to un‐
361       desirable redraws and flicker  if  the  cells  underneath  the  sprixel
362       change.   A  sprixel  which is both a multiple of the cell height and a
363       multiple of six is the most predictable possible sprixel.
364

BUGS

366       Functions which describe  rendered  state  such  as  ncplane_at_yx  and
367       notcurses_at_yx  will  return  an  nccell  with  a sprixel ID, but this
368       sprixel cannot be accessed.
369
370       ncvisual_rotate currently supports only M_PI/2 and -M_PI/2 radians  for
371       rads, but this will change soon.
372
373       ncvisual_render should be able to create new planes in piles other than
374       the standard pile.  This ought become a reality soon.
375
376       Sprixels interact poorly with multiple planes, and such usage  is  dis‐
377       couraged.  This situation might improve in the future.
378
379       Multiple  threads  may  not currently call ncvisual_render concurrently
380       using the same ncvisual, even if  targeting  distinct  ncplanes.   This
381       will likely change in the future.
382

SEE ALSO

384       notcurses(3),  notcurses_capabilities(3),  notcurses_plane(3), notcurs‐
385       es_render(3), utf-8(7)
386

AUTHORS

388       nick black <nickblack@linux.com>.
389
390
391
392                                    v2.3.1                 notcurses_visual(3)
Impressum