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 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                unsigned pxoffy, pxoffx; // pixel offset from origin
49              };
50
51              typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*);
52
53              typedef struct ncvgeom {
54                int pixy, pixx;     // true pixel geometry of ncvisual data
55                int cdimy, cdimx;   // terminal cell geometry when this was calculated
56                int rpixy, rpixx;   // rendered pixel geometry (per visual_options)
57                int rcelly, rcellx; // rendered cell geometry (per visual_options)
58                int scaley, scalex; // pixels per filled cell (scale == c for bitmaps)
59                int maxpixely, maxpixelx; // only defined for NCBLIT_PIXEL
60                int begy, begx;     // upper-left corner of used section
61                int leny, lenx;     // geometry of used section
62                ncblitter_e blitter;// 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, int begy, int begx, int leny, int 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, int y, int x, uint32_t*
120       pixel);
121
122       int ncvisual_set_yx(const struct ncvisual* n, int y,  int  x,  uint32_t
123       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, int* ymax, int* xmax, const void*
140       data, size_t len)
141

DESCRIPTION

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

OPTIONS

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

BLITTERS

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

PIXEL BLITTING

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

RETURN VALUES

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

NOTES

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

BUGS

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

SEE ALSO

441       notcurses(3),  notcurses_capabilities(3),  notcurses_plane(3), notcurs‐
442       es_render(3), utf-8(7)
443

AUTHORS

445       nick black <nickblack@linux.com>.
446
447
448
449                                    v2.4.9                 notcurses_visual(3)
Impressum