Notcurses 3.0.13
a blingful library for TUIs and character graphics
Loading...
Searching...
No Matches
visual.c File Reference
#include <math.h>
#include <string.h>
#include "builddef.h"
#include "visual-details.h"
#include "internal.h"
#include "sixel.h"
Include dependency graph for visual.c:

Go to the source code of this file.

Functions

int ncvisual_init (int logl)
 
void ncvisual_printbanner (fbuf *f)
 
int ncvisual_decode (ncvisual *nc)
 
int ncvisual_decode_loop (ncvisual *nc)
 
ncvisualncvisual_from_file (const char *filename)
 
int ncvisual_stream (notcurses *nc, ncvisual *ncv, float timescale, ncstreamcb streamer, const struct ncvisual_options *vopts, void *curry)
 
ncplanencvisual_subtitle_plane (ncplane *parent, const ncvisual *ncv)
 
int ncvisual_blit_internal (const ncvisual *ncv, int rows, int cols, ncplane *n, const struct blitset *bset, const blitterargs *barg)
 
void ncvisual_details_seed (struct ncvisual *ncv)
 
ncvisualncvisual_create (void)
 
int ncvisual_geom_inner (const tinfo *ti, const ncvisual *n, const struct ncvisual_options *vopts, ncvgeom *geom, const struct blitset **bset, unsigned *disppixy, unsigned *disppixx, unsigned *outy, unsigned *outx, int *placey, int *placex)
 
int ncvisual_geom (const notcurses *nc, const ncvisual *n, const struct ncvisual_options *vopts, ncvgeom *geom)
 
void * rgb_loose_to_rgba (const void *data, int rows, int *rowstride, int cols, int alpha)
 
void * rgb_packed_to_rgba (const void *data, int rows, int *rowstride, int cols, int alpha)
 
void * bgra_to_rgba (const void *data, int rows, int *rowstride, int cols, int alpha)
 
int ncvisual_bounding_box (const ncvisual *ncv, int *leny, int *lenx, int *offy, int *offx)
 
int ncvisual_rotate (ncvisual *ncv, double rads)
 
ncvisualncvisual_from_rgba (const void *rgba, int rows, int rowstride, int cols)
 
ncvisualncvisual_from_sixel (const char *s, unsigned leny, unsigned lenx)
 
ncvisualncvisual_from_rgb_packed (const void *rgba, int rows, int rowstride, int cols, int alpha)
 
ncvisualncvisual_from_rgb_loose (const void *rgba, int rows, int rowstride, int cols, int alpha)
 
ncvisualncvisual_from_bgra (const void *bgra, int rows, int rowstride, int cols)
 
ncvisualncvisual_from_palidx (const void *pdata, int rows, int rowstride, int cols, int palsize, int pstride, const uint32_t *palette)
 
int ncvisual_resize (ncvisual *n, int rows, int cols)
 
int ncvisual_resize_noninterpolative (ncvisual *n, int rows, int cols)
 
ncplanencvisual_render_cells (ncvisual *ncv, const struct blitset *bset, int placey, int placex, ncvgeom *geom, ncplane *n, uint64_t flags, uint32_t transcolor)
 
ncplanencvisual_render_pixels (notcurses *nc, ncvisual *ncv, const struct blitset *bset, int placey, int placex, const ncvgeom *geom, ncplane *n, uint64_t flags, uint32_t transcolor, int pxoffy, int pxoffx)
 
ncplanencvisual_blit (notcurses *nc, ncvisual *ncv, const struct ncvisual_options *vopts)
 
ncvisualncvisual_from_plane (const ncplane *n, ncblitter_e blit, int begy, int begx, unsigned leny, unsigned lenx)
 
void ncvisual_destroy (ncvisual *ncv)
 
int ncvisual_simple_streamer (ncvisual *ncv, struct ncvisual_options *vopts, const struct timespec *tspec, void *curry)
 
int ncvisual_set_yx (const struct ncvisual *n, unsigned y, unsigned x, uint32_t pixel)
 
int ncvisual_at_yx (const ncvisual *n, unsigned y, unsigned x, uint32_t *pixel)
 
int ncvisual_polyfill_yx (ncvisual *n, unsigned y, unsigned x, uint32_t rgba)
 
bool notcurses_canopen_images (const notcurses *nc __attribute__((unused)))
 
bool notcurses_canopen_videos (const notcurses *nc __attribute__((unused)))
 

Variables

ncvisual_implementationvisual_implementation = &null_visual_implementation
 

Function Documentation

◆ bgra_to_rgba()

void * bgra_to_rgba ( const void *  data,
int  rows,
int *  rowstride,
int  cols,
int  alpha 
)

Definition at line 506 of file visual.c.

506 {
507 if(*rowstride % 4){ // must be a multiple of 4 bytes
508 return NULL;
509 }
510 if(*rowstride < cols * 4){
511 return NULL;
512 }
513 uint32_t* ret = malloc(4 * cols * rows);
514 if(ret){
515 for(int y = 0 ; y < rows ; ++y){
516 for(int x = 0 ; x < cols ; ++x){
517 const uint32_t* src = (const uint32_t*)data + (*rowstride / 4) * y + x;
518 uint32_t* dst = ret + cols * y + x;
519 ncpixel_set_a(dst, alpha);
520 ncpixel_set_r(dst, ncpixel_b(*src));
521 ncpixel_set_g(dst, ncpixel_g(*src));
522 ncpixel_set_b(dst, ncpixel_r(*src));
523 }
524 }
525 }
526 *rowstride = cols * 4;
527 return ret;
528}
int y
Definition notcurses.h:1905
int int x
Definition notcurses.h:1905
return NULL
Definition termdesc.h:229
Here is the caller graph for this function:

◆ ncvisual_at_yx()

int ncvisual_at_yx ( const ncvisual n,
unsigned  y,
unsigned  x,
uint32_t *  pixel 
)

Definition at line 1272 of file visual.c.

1272 {
1273 if(y >= n->pixy){
1274 logerror("invalid coordinates %u/%u (%d/%d)", y, x, n->pixy, n->pixx);
1275 return -1;
1276 }
1277 if(x >= n->pixx){
1278 logerror("invalid coordinates %u/%u (%d/%d)", y, x, n->pixy, n->pixx);
1279 return -1;
1280 }
1281 *pixel = n->data[y * (n->rowstride / 4) + x];
1282 return 0;
1283}
#define logerror(fmt,...)
Definition logging.h:32
vopts n
Definition notcurses.h:3502
Here is the caller graph for this function:

◆ ncvisual_blit()

ncplane * ncvisual_blit ( notcurses nc,
ncvisual ncv,
const struct ncvisual_options vopts 
)

Definition at line 1136 of file visual.c.

1136 {
1137//fprintf(stderr, "%p tacache: %p\n", n, n->tacache);
1138 struct ncvisual_options fakevopts;
1139 if(vopts == NULL){
1140 memset(&fakevopts, 0, sizeof(fakevopts));
1141 vopts = &fakevopts;
1142 }
1143 loginfo("inblit %dx%d %d@%d %dx%d @ %dx%d %p", ncv->pixy, ncv->pixx, vopts->y, vopts->x,
1144 vopts->leny, vopts->lenx, vopts->begy, vopts->begx, vopts->n);
1145 ncvgeom geom;
1146 const struct blitset* bset;
1147 unsigned disppxy, disppxx, outy, outx;
1148 int placey, placex;
1149 if(ncvisual_geom_inner(&nc->tcache, ncv, vopts, &geom, &bset,
1150 &disppxy, &disppxx, &outy, &outx,
1151 &placey, &placex)){
1152 // ncvisual_blitset_geom() emits its own diagnostics, no need for an error here
1153 return NULL;
1154 }
1155 ncplane* n = vopts->n;
1156 uint32_t transcolor = 0;
1158 transcolor = 0x1000000ull | vopts->transcolor;
1159 }
1160 ncplane* createdn = NULL; // to destroy on error
1161 if(n == NULL || (vopts->flags & NCVISUAL_OPTION_CHILDPLANE)){ // create plane
1162 struct ncplane_options nopts = {
1163 .y = placey,
1164 .x = placex,
1165 .rows = geom.rcelly,
1166 .cols = geom.rcellx,
1167 .userptr = NULL,
1168 .name = geom.blitter == NCBLIT_PIXEL ? "bmap" : "cvis",
1169 .resizecb = NULL,
1170 .flags = 0,
1171 };
1174 nopts.x = vopts->x;
1175 }
1178 nopts.y = vopts->y;
1179 }
1180 loginfo("placing new plane: %d/%d @ %d/%d 0x%016" PRIx64, nopts.rows, nopts.cols, nopts.y, nopts.x, nopts.flags);
1181 if(n == NULL){
1182 n = ncpile_create(nc, &nopts);
1183 }else{
1184 n = ncplane_create(n, &nopts);
1185 }
1186 if((createdn = n) == NULL){
1187 return NULL;
1188 }
1189 placey = 0;
1190 placex = 0;
1191 }
1192 logdebug("blit to plane %p at %d/%d geom %dx%d", n, ncplane_abs_y(n), ncplane_abs_x(n), ncplane_dim_y(n), ncplane_dim_x(n));
1193 if(geom.blitter != NCBLIT_PIXEL){
1194 n = ncvisual_render_cells(ncv, bset, placey, placex,
1195 &geom, n, vopts->flags, transcolor);
1196 }else{
1197 n = ncvisual_render_pixels(nc, ncv, bset, placey, placex,
1198 &geom, n,
1199 vopts->flags, transcolor,
1200 vopts->pxoffy, vopts->pxoffx);
1201 }
1202 if(n == NULL){
1203 ncplane_destroy(createdn);
1204 }
1205 return n;
1206}
#define loginfo(fmt,...)
Definition logging.h:42
#define logdebug(fmt,...)
Definition logging.h:52
int ncplane_abs_x(const ncplane *n)
Definition notcurses.c:2638
ncplane * ncpile_create(notcurses *nc, const struct ncplane_options *nopts)
Definition notcurses.c:711
int ncplane_destroy(ncplane *ncp)
Definition notcurses.c:1018
int ncplane_abs_y(const ncplane *n)
Definition notcurses.c:2634
ncplane * ncplane_create(ncplane *n, const ncplane_options *nopts)
Definition notcurses.c:707
#define NCVISUAL_OPTION_CHILDPLANE
Definition notcurses.h:3342
const struct ncplane_options struct ncvisual * ncv
Definition notcurses.h:3484
#define NCPLANE_OPTION_HORALIGNED
Definition notcurses.h:1441
const struct ncplane_options struct ncvisual struct ncvisual_options * vopts
Definition notcurses.h:3484
#define NCPLANE_OPTION_VERALIGNED
Definition notcurses.h:1443
@ NCBLIT_PIXEL
Definition notcurses.h:73
#define NCVISUAL_OPTION_ADDALPHA
Definition notcurses.h:3341
#define NCVISUAL_OPTION_VERALIGNED
Definition notcurses.h:3340
#define NCVISUAL_OPTION_HORALIGNED
Definition notcurses.h:3339
ncblitter_e geom
Definition internal.h:399
ncblitter_e blitter
Definition notcurses.h:3406
unsigned rcellx
Definition notcurses.h:3401
unsigned rcelly
Definition notcurses.h:3401
tinfo tcache
Definition internal.h:360
ncplane * ncvisual_render_pixels(notcurses *nc, ncvisual *ncv, const struct blitset *bset, int placey, int placex, const ncvgeom *geom, ncplane *n, uint64_t flags, uint32_t transcolor, int pxoffy, int pxoffx)
Definition visual.c:1050
int ncvisual_geom_inner(const tinfo *ti, const ncvisual *n, const struct ncvisual_options *vopts, ncvgeom *geom, const struct blitset **bset, unsigned *disppixy, unsigned *disppixx, unsigned *outy, unsigned *outx, int *placey, int *placex)
Definition visual.c:208
ncplane * ncvisual_render_cells(ncvisual *ncv, const struct blitset *bset, int placey, int placex, ncvgeom *geom, ncplane *n, uint64_t flags, uint32_t transcolor)
Definition visual.c:1013
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_blit_internal()

int ncvisual_blit_internal ( const ncvisual ncv,
int  rows,
int  cols,
ncplane n,
const struct blitset bset,
const blitterargs barg 
)

Definition at line 84 of file visual.c.

85 {
88 if(visual_implementation->visual_blit(ncv, rows, cols, n, bset, barg) < 0){
89 return -1;
90 }
91 return 0;
92 }
93 }
94 // generic implementation
95 int stride = 4 * cols;
96 uint32_t* data = resize_bitmap(ncv->data, ncv->pixy, ncv->pixx,
97 ncv->rowstride, rows, cols, stride);
98 if(data == NULL){
99 return -1;
100 }
101 int ret = -1;
102 if(rgba_blit_dispatch(n, bset, stride, data, rows, cols, barg) >= 0){
103 ret = 0;
104 }
105 if(data != ncv->data){
106 free(data);
107 }
108 return ret;
109}
free(duplicated)
#define NCVISUAL_OPTION_NOINTERPOLATE
Definition notcurses.h:3343
uint64_t flags
Definition internal.h:379
int(* visual_blit)(const struct ncvisual *ncv, unsigned rows, unsigned cols, ncplane *n, const struct blitset *bset, const blitterargs *barg)
Definition internal.h:1797
ncvisual_implementation * visual_implementation
Definition visual.c:20
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_bounding_box()

int ncvisual_bounding_box ( const ncvisual ncv,
int *  leny,
int *  lenx,
int *  offy,
int *  offx 
)

Definition at line 534 of file visual.c.

535 {
536 unsigned lcol = 0;
537 unsigned rcol = UINT_MAX;
538 unsigned trow;
539 // first, find the topmost row with a real pixel. if there is no such row,
540 // there are no such pixels. if we find one, we needn't look in this region
541 // for other extrema, so long as we keep the leftmost and rightmost through
542 // this row (from the top). said leftmost and rightmost will be the leftmost
543 // and rightmost pixel of whichever row has the topmost valid pixel. unlike
544 // the topmost, they'll need be further verified.
545 for(trow = 0 ; trow < ncv->pixy ; ++trow){
546 for(unsigned x = 0 ; x < ncv->pixx ; ++x){
547 uint32_t rgba = ncv->data[trow * ncv->rowstride / 4 + x];
548 if(rgba){
549 lcol = x; // leftmost pixel of topmost row
550 // now find rightmost pixel of topmost row
551 unsigned xr;
552 for(xr = ncv->pixx - 1 ; xr > x ; --xr){
553 rgba = ncv->data[trow * ncv->rowstride / 4 + xr];
554 if(rgba){ // rightmost pixel of topmost row
555 break;
556 }
557 }
558 rcol = xr;
559 break;
560 }
561 }
562 if(rcol < INT_MAX){
563 break;
564 }
565 }
566 if(trow == ncv->pixy){ // no real pixels
567 *leny = 0;
568 *lenx = 0;
569 *offy = 0;
570 *offx = 0;
571 }else{
572 assert(rcol < ncv->pixx);
573 // we now know topmost row, and left/rightmost through said row. now we must
574 // find the bottommost row, checking left/rightmost throughout.
575 unsigned brow;
576 for(brow = ncv->pixy - 1 ; brow > trow ; --brow){
577 unsigned x;
578 for(x = 0 ; x < ncv->pixx ; ++x){
579 uint32_t rgba = ncv->data[brow * ncv->rowstride / 4 + x];
580 if(rgba){
581 if(x < lcol){
582 lcol = x;
583 }
584 unsigned xr;
585 for(xr = ncv->pixx - 1 ; xr > x && xr > rcol ; --xr){
586 rgba = ncv->data[brow * ncv->rowstride / 4 + xr];
587 if(rgba){ // rightmost pixel of bottommost row
588 if(xr > rcol){
589 rcol = xr;
590 }
591 break;
592 }
593 }
594 break;
595 }
596 }
597 if(x < ncv->pixx){
598 break;
599 }
600 }
601 // we now know topmost and bottommost row, and left/rightmost within those
602 // two sections. now check the rest for left and rightmost.
603 for(unsigned y = trow + 1 ; y < brow ; ++y){
604 for(unsigned x = 0 ; x < lcol ; ++x){
605 uint32_t rgba = ncv->data[y * ncv->rowstride / 4 + x];
606 if(rgba){
607 lcol = x;
608 break;
609 }
610 }
611 for(unsigned x = ncv->pixx - 1 ; x > rcol ; --x){
612 uint32_t rgba = ncv->data[y * ncv->rowstride / 4 + x];
613 if(rgba){
614 rcol = x;
615 break;
616 }
617 }
618 }
619 *offy = trow;
620 *leny = brow - trow + 1;
621 *offx = lcol;
622 *lenx = rcol - lcol + 1;
623 }
624 return *leny * *lenx;
625}
assert(false)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_create()

ncvisual * ncvisual_create ( void  )

Definition at line 120 of file visual.c.

120 {
123 }
124 ncvisual* ret = malloc(sizeof(*ret));
125 if(ret){
126 memset(ret, 0, sizeof(*ret));
127 }
128 return ret;
129}
struct ncvisual *(* visual_create)(void)
Definition internal.h:1799
Here is the caller graph for this function:

◆ ncvisual_decode()

int ncvisual_decode ( ncvisual nc)

Definition at line 39 of file visual.c.

39 {
41 return -1;
42 }
44}
int(* visual_decode)(struct ncvisual *nc)
Definition internal.h:1805
Here is the caller graph for this function:

◆ ncvisual_decode_loop()

int ncvisual_decode_loop ( ncvisual nc)

Definition at line 46 of file visual.c.

46 {
48 return -1;
49 }
51}
int(* visual_decode_loop)(struct ncvisual *nc)
Definition internal.h:1806
Here is the caller graph for this function:

◆ ncvisual_destroy()

void ncvisual_destroy ( ncvisual ncv)

Definition at line 1225 of file visual.c.

1225 {
1226 if(ncv){
1228 if(ncv->owndata){
1229 free(ncv->data);
1230 }
1231 free(ncv);
1232 }else{
1234 }
1235 }
1236}
void(* visual_destroy)(struct ncvisual *ncv)
Definition internal.h:1813
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_details_seed()

void ncvisual_details_seed ( struct ncvisual ncv)

Definition at line 114 of file visual.c.

114 {
117 }
118}
void(* visual_details_seed)(struct ncvisual *ncv)
Definition internal.h:1804
Here is the caller graph for this function:

◆ ncvisual_from_bgra()

ncvisual * ncvisual_from_bgra ( const void *  bgra,
int  rows,
int  rowstride,
int  cols 
)

Definition at line 891 of file visual.c.

891 {
892 if(rowstride % 4){
893 logerror("rowstride %d not a multiple of 4", rowstride);
894 return NULL;
895 }
896 if(rows <= 0 || cols <= 0 || rowstride < cols * 4){
897 logerror("illegal bgra geometry");
898 return NULL;
899 }
901 if(ncv){
902 ncv->rowstride = pad_for_image(rowstride, cols);
903 ncv->pixx = cols;
904 ncv->pixy = rows;
905 uint32_t* data = malloc(ncv->rowstride * ncv->pixy);
906 if(data == NULL){
908 return NULL;
909 }
910 for(int y = 0 ; y < rows ; ++y){
911 for(int x = 0 ; x < cols ; ++x){
912 uint32_t src;
913 memcpy(&src, (const char*)bgra + y * rowstride + x * 4, 4);
914 uint32_t* dst = &data[ncv->rowstride * y / 4 + x];
915 ncpixel_set_a(dst, ncpixel_a(src));
916 ncpixel_set_r(dst, ncpixel_b(src));
917 ncpixel_set_g(dst, ncpixel_g(src));
918 ncpixel_set_b(dst, ncpixel_r(src));
919//fprintf(stderr, "BGRA PIXEL: %02x%02x%02x%02x RGBA result: %02x%02x%02x%02x\n", ((const char*)&src)[0], ((const char*)&src)[1], ((const char*)&src)[2], ((const char*)&src)[3], ((const char*)dst)[0], ((const char*)dst)[1], ((const char*)dst)[2], ((const char*)dst)[3]);
920 }
921 }
922 ncvisual_set_data(ncv, data, true);
924 }
925 return ncv;
926}
void ncvisual_details_seed(struct ncvisual *ncv)
Definition visual.c:114
void ncvisual_destroy(ncvisual *ncv)
Definition visual.c:1225
ncvisual * ncvisual_create(void)
Definition visual.c:120
Here is the call graph for this function:

◆ ncvisual_from_file()

ncvisual * ncvisual_from_file ( const char *  filename)

Definition at line 53 of file visual.c.

53 {
55 return NULL;
56 }
58 if(n == NULL){
59 logerror("error loading %s", filename);
60 }
61 return n;
62}
struct ncvisual *(* visual_from_file)(const char *fname)
Definition internal.h:1800
Here is the caller graph for this function:

◆ ncvisual_from_palidx()

ncvisual * ncvisual_from_palidx ( const void *  pdata,
int  rows,
int  rowstride,
int  cols,
int  palsize,
int  pstride,
const uint32_t *  palette 
)

Definition at line 928 of file visual.c.

930 {
931 if(pstride <= 0 || rowstride % pstride){
932 logerror("bad pstride (%d) for rowstride (%d)", pstride, rowstride);
933 return NULL;
934 }
935 if(rows <= 0 || cols <= 0 || rowstride < cols * pstride){
936 logerror("illegal palimg geometry");
937 return NULL;
938 }
939 if(palsize > 256 || palsize <= 0){
940 logerror("palettes size (%d) is unsupported", palsize);
941 return NULL;
942 }
944 if(ncv){
945 ncv->rowstride = pad_for_image(rowstride, cols);
946 ncv->pixx = cols;
947 ncv->pixy = rows;
948 uint32_t* data = malloc(ncv->rowstride * ncv->pixy);
949 if(data == NULL){
951 return NULL;
952 }
953 for(int y = 0 ; y < rows ; ++y){
954 for(int x = 0 ; x < cols ; ++x){
955 int palidx = ((const unsigned char*)pdata)[y * rowstride + x * pstride];
956 if(palidx >= palsize){
957 free(data);
959 logerror("invalid palette idx %d >= %d", palidx, palsize);
960 return NULL;
961 }
962 uint32_t src = palette[palidx];
963 uint32_t* dst = &data[ncv->rowstride * y / 4 + x];
964 if(ncchannel_default_p(src)){
965 // FIXME use default color as detected, or just 0xffffff
966 ncpixel_set_a(dst, 255 - palidx);
967 ncpixel_set_r(dst, palidx);
968 ncpixel_set_g(dst, 220 - (palidx / 2));
969 ncpixel_set_b(dst, palidx);
970 }else{
971 *dst = 0;
972 }
973//fprintf(stderr, "BGRA PIXEL: %02x%02x%02x%02x RGBA result: %02x%02x%02x%02x\n", ((const char*)&src)[0], ((const char*)&src)[1], ((const char*)&src)[2], ((const char*)&src)[3], ((const char*)dst)[0], ((const char*)dst)[1], ((const char*)dst)[2], ((const char*)dst)[3]);
974 }
975 }
976 ncvisual_set_data(ncv, data, true);
978 }
979 return ncv;
980}
Here is the call graph for this function:

◆ ncvisual_from_plane()

ncvisual * ncvisual_from_plane ( const ncplane n,
ncblitter_e  blit,
int  begy,
int  begx,
unsigned  leny,
unsigned  lenx 
)

Definition at line 1208 of file visual.c.

1210 {
1211 unsigned py, px;
1212 uint32_t* rgba = ncplane_as_rgba(n, blit, begy, begx, leny, lenx, &py, &px);
1213//fprintf(stderr, "snarg: %d/%d @ %d/%d (%p)\n", leny, lenx, begy, begx, rgba);
1214 if(rgba == NULL){
1215 return NULL;
1216 }
1217 unsigned dimy, dimx;
1218 ncplane_dim_yx(n, &dimy, &dimx);
1219 ncvisual* ncv = ncvisual_from_rgba(rgba, py, px * 4, px);
1220 free(rgba);
1221//fprintf(stderr, "RETURNING %p\n", ncv);
1222 return ncv;
1223}
uint32_t * ncplane_as_rgba(const ncplane *nc, ncblitter_e blit, int begy, int begx, unsigned leny, unsigned lenx, unsigned *pxdimy, unsigned *pxdimx)
Definition notcurses.c:3214
void ncplane_dim_yx(const ncplane *n, unsigned *rows, unsigned *cols)
Definition notcurses.c:301
ncvisual * ncvisual_from_rgba(const void *rgba, int rows, int rowstride, int cols)
Definition visual.c:776
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_from_rgb_loose()

ncvisual * ncvisual_from_rgb_loose ( const void *  rgba,
int  rows,
int  rowstride,
int  cols,
int  alpha 
)

Definition at line 858 of file visual.c.

859 {
860 if(rowstride % 4){
861 logerror("rowstride %d not a multiple of 4", rowstride);
862 return NULL;
863 }
864 if(rows <= 0 || cols <= 0 || rowstride < cols * 4){
865 logerror("illegal packed rgb geometry");
866 return NULL;
867 }
869 if(ncv){
870 ncv->rowstride = pad_for_image(cols * 4, cols);
871 ncv->pixx = cols;
872 ncv->pixy = rows;
873 uint32_t* data = malloc(ncv->rowstride * ncv->pixy);
874 if(data == NULL){
876 return NULL;
877 }
878 for(int y = 0 ; y < rows ; ++y){
879//fprintf(stderr, "ROWS: %d STRIDE: %d (%d) COLS: %d %08x\n", ncv->pixy, ncv->rowstride, ncv->rowstride / 4, cols, data[ncv->rowstride * y / 4]);
880 memcpy(data + (ncv->rowstride * y) / 4, (const char*)rgba + rowstride * y, rowstride);
881 for(int x = 0 ; x < cols ; ++x){
882 ncpixel_set_a(&data[y * ncv->rowstride / 4 + x], alpha);
883 }
884 }
885 ncvisual_set_data(ncv, data, true);
887 }
888 return ncv;
889}
Here is the call graph for this function:

◆ ncvisual_from_rgb_packed()

ncvisual * ncvisual_from_rgb_packed ( const void *  rgba,
int  rows,
int  rowstride,
int  cols,
int  alpha 
)

Definition at line 817 of file visual.c.

818 {
819 if(rowstride % 3){
820 logerror("rowstride %d not a multiple of 3", rowstride);
821 return NULL;
822 }
823 if(rows <= 0 || cols <= 0 || rowstride < cols * 3){
824 logerror("illegal packed rgb geometry");
825 return NULL;
826 }
828 if(ncv){
829 ncv->rowstride = pad_for_image(cols * 4, cols);
830 ncv->pixx = cols;
831 ncv->pixy = rows;
832 uint32_t* data = malloc(ncv->rowstride * ncv->pixy);
833 if(data == NULL){
835 return NULL;
836 }
837 const unsigned char* src = rgba;
838 for(int y = 0 ; y < rows ; ++y){
839//fprintf(stderr, "ROWS: %d STRIDE: %d (%d) COLS: %d %08x\n", ncv->pixy, ncv->rowstride, ncv->rowstride / 4, cols, data[ncv->rowstride * y / 4]);
840 for(int x = 0 ; x < cols ; ++x){
841 unsigned char r, g, b;
842 memcpy(&r, src + rowstride * y + 3 * x, 1);
843 memcpy(&g, src + rowstride * y + 3 * x + 1, 1);
844 memcpy(&b, src + rowstride * y + 3 * x + 2, 1);
845 ncpixel_set_a(&data[y * ncv->rowstride / 4 + x], alpha);
846 ncpixel_set_r(&data[y * ncv->rowstride / 4 + x], r);
847 ncpixel_set_g(&data[y * ncv->rowstride / 4 + x], g);
848 ncpixel_set_b(&data[y * ncv->rowstride / 4 + x], b);
849//fprintf(stderr, "RGBA: 0x%02x 0x%02x 0x%02x 0x%02x\n", r, g, b, alpha);
850 }
851 }
852 ncvisual_set_data(ncv, data, true);
854 }
855 return ncv;
856}
int r
Definition fbuf.h:226
Here is the call graph for this function:

◆ ncvisual_from_rgba()

ncvisual * ncvisual_from_rgba ( const void *  rgba,
int  rows,
int  rowstride,
int  cols 
)

Definition at line 776 of file visual.c.

776 {
777 if(rowstride % 4){
778 logerror("rowstride %d not a multiple of 4", rowstride);
779 return NULL;
780 }
781 if(rowstride * 4 < cols || cols <= 0 || rows <= 0){
782 logerror("invalid rowstride or geometry");
783 return NULL;
784 }
786 if(ncv){
787 // ffmpeg needs inputs with rows aligned on 192-byte boundaries
788 ncv->rowstride = pad_for_image(rowstride, cols);
789 ncv->pixx = cols;
790 ncv->pixy = rows;
791 uint32_t* data = malloc(ncv->rowstride * ncv->pixy);
792 if(data == NULL){
794 return NULL;
795 }
796 for(int y = 0 ; y < rows ; ++y){
797//fprintf(stderr, "ROWS: %d STRIDE: %d (%d) COLS: %d %08x\n", ncv->pixy, ncv->rowstride, rowstride, cols, data[ncv->rowstride * y / 4]);
798 memcpy(data + (ncv->rowstride * y) / 4, (const char*)rgba + rowstride * y, rowstride);
799 }
800 ncvisual_set_data(ncv, data, true);
802 }
803 return ncv;
804}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_from_sixel()

ncvisual * ncvisual_from_sixel ( const char *  s,
unsigned  leny,
unsigned  lenx 
)

Definition at line 806 of file visual.c.

806 {
807 uint32_t* rgba = ncsixel_as_rgba(s, leny, lenx);
808 if(rgba == NULL){
809 logerror("failed converting sixel to rgba");
810 return NULL;
811 }
812 ncvisual* ncv = ncvisual_from_rgba(rgba, leny, lenx * sizeof(*rgba), lenx);
813 free(rgba);
814 return ncv;
815}
uint32_t * ncsixel_as_rgba(const char *sx, unsigned leny, unsigned lenx)
Definition sixel.h:12
Here is the call graph for this function:

◆ ncvisual_geom()

int ncvisual_geom ( const notcurses nc,
const ncvisual n,
const struct ncvisual_options vopts,
ncvgeom geom 
)

Definition at line 452 of file visual.c.

453 {
454 const struct blitset* bset;
455 unsigned disppxy, disppxx, outy, outx;
456 int placey, placex;
457 return ncvisual_geom_inner(nc ? &nc->tcache : NULL, n, vopts, geom, &bset,
458 &disppxy, &disppxx, &outy, &outx, &placey, &placex);
459}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_geom_inner()

int ncvisual_geom_inner ( const tinfo ti,
const ncvisual n,
const struct ncvisual_options vopts,
ncvgeom geom,
const struct blitset **  bset,
unsigned *  disppixy,
unsigned *  disppixx,
unsigned *  outy,
unsigned *  outx,
int *  placey,
int *  placex 
)

Definition at line 208 of file visual.c.

213 {
214 if(ti == NULL && n == NULL){
215 logerror("got NULL for both sources");
216 return -1;
217 }
218 struct ncvisual_options fakevopts;
219 if(vopts == NULL){
220 memset(&fakevopts, 0, sizeof(fakevopts));
221 vopts = &fakevopts;
222 }
223 // check basic vopts preconditions
225 logwarn("warning: unknown ncvisual options %016" PRIx64, vopts->flags);
226 }
228 logerror("requested child plane with NULL n");
229 return -1;
230 }
233 logerror("bad x %d for horizontal alignment", vopts->x);
234 return -1;
235 }
236 }
239 logerror("bad y %d for vertical alignment", vopts->y);
240 return -1;
241 }
242 }
243 if(n){
244 geom->pixy = n->pixy;
245 geom->pixx = n->pixx;
246 }
247 // when ti is NULL, we only report properties intrinsic to the ncvisual,
248 // i.e. only its original pixel geometry.
249 if(ti == NULL){
250 return 0;
251 }
252 // determine our blitter
253 *bset = rgba_blitter(ti, vopts);
254 if(!*bset){
255 logerror("couldn't get a blitter for %d", vopts ? vopts->blitter : NCBLIT_DEFAULT);
256 return -1;
257 }
258 const ncpile* p = vopts->n ? ncplane_pile_const(vopts->n) : NULL;
259 geom->cdimy = p ? p->cellpxy : ti->cellpxy;
260 geom->cdimx = p ? p->cellpxx : ti->cellpxx;
261 if((geom->blitter = (*bset)->geom) == NCBLIT_PIXEL){
262 geom->maxpixely = ti->sixel_maxy;
263 geom->maxpixelx = ti->sixel_maxx;
264 }
265 geom->scaley = encoding_y_scale(ti, *bset);
266 geom->scalex = encoding_x_scale(ti, *bset);
267 // when n is NULL, we only report properties unrelated to the ncvisual,
268 // i.e. the cell-pixel geometry, max bitmap geometry, blitter, and scaling.
269 if(n == NULL){
270 return 0;
271 }
273 // determine how much of the original image we're using (leny/lenx)
274 ncvisual_origin(vopts, &geom->begy, &geom->begx);
275 geom->lenx = vopts->lenx;
276 geom->leny = vopts->leny;
277 *placey = vopts->y;
278 *placex = vopts->x;
279 logdebug("vis %ux%u+%ux%u %p", geom->begy, geom->begx, geom->leny, geom->lenx, n->data);
280 if(n->data == NULL){
281 logerror("no data in visual");
282 return -1;
283 }
284 if(geom->begx >= n->pixx || geom->begy >= n->pixy){
285 logerror("visual too large %u > %d or %u > %d", geom->begy, n->pixy, geom->begx, n->pixx);
286 return -1;
287 }
288 if(geom->lenx == 0){ // 0 means "to the end"; use all available source material
289 geom->lenx = n->pixx - geom->begx;
290 }
291 if(geom->leny == 0){
292 geom->leny = n->pixy - geom->begy;
293 }
294 if(geom->lenx <= 0 || geom->leny <= 0){ // no need to draw zero-size object, exit
295 logerror("zero-size object %d %d", geom->leny, geom->lenx);
296 return -1;
297 }
298 if(geom->begx + geom->lenx > n->pixx || geom->begy + geom->leny > n->pixy){
299 logerror("geometry too large %d > %d or %d > %d", geom->begy + geom->leny, n->pixy, geom->begx + geom->lenx, n->pixx);
300 return -1;
301 }
302 if((*bset)->geom == NCBLIT_PIXEL){
303 if(vopts->n){
304 // FIXME does this work from direct mode?
307 logerror("won't blit bitmaps to the standard plane");
308 return -1;
309 }
310 }
312 logerror("non-origin y placement %d for sprixel", vopts->y);
313 return -1;
314 }
316 logerror("non-origin x placement %d for sprixel", vopts->x);
317 return -1;
318 }
319 if(vopts->pxoffy >= geom->cdimy){
320 logerror("pixel y-offset %d too tall for cell %d", vopts->pxoffy, geom->cdimy);
321 return -1;
322 }
323 if(vopts->pxoffx >= geom->cdimx){
324 logerror("pixel x-offset %d too wide for cell %d", vopts->pxoffx, geom->cdimx);
325 return -1;
326 }
328 // FIXME clamp to sprixel limits
329 unsigned rows = ((geom->leny + geom->cdimy - 1) / geom->cdimy) + !!vopts->pxoffy;
330 if(rows > ncplane_dim_y(vopts->n)){
331 logerror("sprixel too tall %d for plane %d", geom->leny + vopts->pxoffy,
332 ncplane_dim_y(vopts->n) * geom->cdimy);
333 return -1;
334 }
335 unsigned cols = ((geom->lenx + geom->cdimx - 1) / geom->cdimx) + !!vopts->pxoffx;
336 if(cols > ncplane_dim_x(vopts->n)){
337 logerror("sprixel too wide %d for plane %d", geom->lenx + vopts->pxoffx,
338 ncplane_dim_x(vopts->n) * geom->cdimx);
339 return -1;
340 }
341 }
342 }
344 // we'll need to create the plane
345 const int dimy = p ? p->dimy : ti->dimy;
346 const int dimx = p ? p->dimx : ti->dimx;
347 shape_sprixel_plane(ti, geom->cdimy, geom->cdimx, dimy, dimx,
348 vopts->n, n, scaling, disppixy, disppixx,
349 vopts->flags, outy, outx, placey, placex,
350 vopts->pxoffy, vopts->pxoffx);
351 }else{
353 ncplane_dim_yx(vopts->n, disppixy, disppixx);
354 *disppixx *= geom->cdimx;
355 *disppixx += vopts->pxoffx;
356 *disppixy *= geom->cdimy;
357 *disppixy += vopts->pxoffy;
358 clamp_to_sixelmax(ti, disppixy, disppixx, outy, scaling);
359 int absplacex = 0, absplacey = 0;
361 absplacex = *placex;
362 }
364 absplacey = *placey;
365 }
366 *disppixx -= absplacex * geom->cdimx;
367 *disppixy -= absplacey * geom->cdimy;
368 }else{
369 *disppixx = geom->lenx + vopts->pxoffx;
370 *disppixy = geom->leny + vopts->pxoffy;
371 }
372 logdebug("pixel prescale: %d %d %d %d", n->pixy, n->pixx, *disppixy, *disppixx);
374 clamp_to_sixelmax(ti, disppixy, disppixx, outy, scaling);
375 scale_visual(n, disppixy, disppixx);
376 }
377 clamp_to_sixelmax(ti, disppixy, disppixx, outy, scaling);
378 // FIXME use a closed form
379 while((*outy + geom->cdimy - 1) / geom->cdimy > ncplane_dim_y(vopts->n)){
380 *outy -= ti->sprixel_scale_height;
381 *disppixy = *outy;
382 }
383 *outx = *disppixx;
384 *disppixx -= vopts->pxoffx;
385 *disppixy -= vopts->pxoffy;
386 }
387 logdebug("pblit: %dx%d ← %dx%d of %d/%d stride %u @%dx%d %p %u", *disppixy, *disppixx, geom->begy, geom->begx, n->pixy, n->pixx, n->rowstride, *placey, *placex, n->data, geom->cdimx);
388 geom->rpixy = *disppixy;
389 geom->rpixx = *disppixx;
390 geom->rcellx = *outx / geom->cdimx + !!(*outx % geom->cdimx);
391 geom->rcelly = *outy / geom->cdimy + !!(*outy % geom->cdimy);
392 }else{ // cellblit
393 if(vopts->pxoffx || vopts->pxoffy){
394 logerror("pixel offsets cannot be used with cell blitting");
395 return -1;
396 }
397 unsigned dispcols, disprows;
398 if(vopts->n == NULL || (vopts->flags & NCVISUAL_OPTION_CHILDPLANE)){ // create plane
399//fprintf(stderr, "CPATH1, create beg %dx%d len %dx%d\n", geom->begy, geom->begx, geom->leny, geom->lenx);
401 dispcols = geom->lenx;
402 disprows = geom->leny;
403 }else{
404 if(vopts->n == NULL){
405 disprows = ti->dimy;
406 dispcols = ti->dimx;
407 }else{
408 ncplane_dim_yx(vopts->n, &disprows, &dispcols);
409 }
410 dispcols *= geom->scalex;
411 disprows *= geom->scaley;
413 scale_visual(n, &disprows, &dispcols);
414 } // else stretch
415 }
416 }else{
417//fprintf(stderr, "CPATH2, reuse beg %dx%d len %dx%d\n", geom->begy, geom->begx, geom->leny, geom->lenx);
419 dispcols = geom->lenx;
420 disprows = geom->leny;
421 }else{
422 ncplane_dim_yx(vopts->n, &disprows, &dispcols);
423 dispcols *= geom->scalex;
424 disprows *= geom->scaley;
426 dispcols -= *placex;
427 }
429 disprows -= *placey;
430 }
432 scale_visual(n, &disprows, &dispcols);
433 } // else stretch
434 }
436 *placex = ncplane_halign(vopts->n, *placex, dispcols / geom->scalex);
437 }
439 *placey = ncplane_valign(vopts->n, *placey, disprows / geom->scaley);
440 }
441 }
442 geom->rpixy = disprows;
443 geom->rpixx = dispcols;
444 geom->rcellx = dispcols / geom->scalex + !!(dispcols % geom->scalex);
445 geom->rcelly = disprows / geom->scaley + !!(disprows % geom->scaley);
446 }
447 logdebug("rgeom: %d %d %d %d @ %d/%d (%d on %p)", geom->rcelly, geom->rcellx,
448 geom->rpixy, geom->rpixx, *placey, *placex, (*bset)->geom, vopts->n);
449 return 0;
450}
#define logwarn(fmt,...)
Definition logging.h:37
const notcurses * ncplane_notcurses_const(const ncplane *n)
Definition notcurses.c:2630
const ncplane * notcurses_stdplane_const(const notcurses *nc)
Definition notcurses.c:703
ncscale_e
Definition notcurses.h:96
@ NCSCALE_SCALE_HIRES
Definition notcurses.h:101
@ NCSCALE_SCALE
Definition notcurses.h:98
@ NCSCALE_NONE
Definition notcurses.h:97
@ NCSCALE_NONE_HIRES
Definition notcurses.h:100
@ NCALIGN_UNALIGNED
Definition notcurses.h:81
@ NCALIGN_RIGHT
Definition notcurses.h:84
@ NCBLIT_DEFAULT
Definition notcurses.h:66
unsigned cellpxx
Definition internal.h:326
unsigned dimx
Definition internal.h:325
unsigned dimy
Definition internal.h:325
unsigned cellpxy
Definition internal.h:326
unsigned rpixx
Definition notcurses.h:3400
unsigned cdimx
Definition notcurses.h:3399
unsigned scaley
Definition notcurses.h:3402
unsigned lenx
Definition notcurses.h:3404
unsigned pixx
Definition notcurses.h:3398
unsigned pixy
Definition notcurses.h:3398
unsigned rpixy
Definition notcurses.h:3400
unsigned begy
Definition notcurses.h:3403
unsigned maxpixelx
Definition notcurses.h:3405
unsigned maxpixely
Definition notcurses.h:3405
unsigned begx
Definition notcurses.h:3403
unsigned leny
Definition notcurses.h:3404
unsigned cdimy
Definition notcurses.h:3399
unsigned scalex
Definition notcurses.h:3402
ncscale_e scaling
Definition notcurses.h:3354
unsigned cellpxx
Definition termdesc.h:117
unsigned dimx
Definition termdesc.h:118
unsigned sprixel_scale_height
Definition termdesc.h:174
unsigned sixel_maxx
Definition termdesc.h:165
unsigned dimy
Definition termdesc.h:118
unsigned sixel_maxy
Definition termdesc.h:172
unsigned cellpxy
Definition termdesc.h:116
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_init()

int ncvisual_init ( int  logl)

Definition at line 23 of file visual.c.

23 {
26 }
27 return 0;
28}
int(* visual_init)(int loglevel)
Definition internal.h:1795
Here is the caller graph for this function:

◆ ncvisual_polyfill_yx()

int ncvisual_polyfill_yx ( ncvisual n,
unsigned  y,
unsigned  x,
uint32_t  rgba 
)

Definition at line 1344 of file visual.c.

1344 {
1345 if(y >= n->pixy){
1346 logerror("invalid coordinates %u/%u", y, x);
1347 return -1;
1348 }
1349 if(x >= n->pixx){
1350 logerror("invalid coordinates %u/%u", y, x);
1351 return -1;
1352 }
1353 uint32_t* pixel = &n->data[y * (n->rowstride / 4) + x];
1354 return ncvisual_polyfill_core(n, y, x, rgba, *pixel);
1355}
Here is the caller graph for this function:

◆ ncvisual_printbanner()

void ncvisual_printbanner ( fbuf f)

Definition at line 30 of file visual.c.

Here is the caller graph for this function:

◆ ncvisual_render_cells()

ncplane * ncvisual_render_cells ( ncvisual ncv,
const struct blitset bset,
int  placey,
int  placex,
ncvgeom geom,
ncplane n,
uint64_t  flags,
uint32_t  transcolor 
)

Definition at line 1013 of file visual.c.

1016 {
1017 logdebug("cblit: rows/cols: %dx%d plane: %d/%d pix: %d/%d", geom->rcelly, geom->rcellx, ncplane_dim_y(n), ncplane_dim_x(n), geom->rpixy, geom->rpixx);
1018 blitterargs bargs;
1019 bargs.transcolor = transcolor;
1020 bargs.begy = geom->begy;
1021 bargs.begx = geom->begx;
1022 bargs.leny = geom->leny;
1023 bargs.lenx = geom->lenx;
1024 bargs.flags = flags;
1025 bargs.u.cell.placey = placey;
1026 bargs.u.cell.placex = placex;
1027 if(ncvisual_blit_internal(ncv, geom->rpixy, geom->rpixx, n, bset, &bargs)){
1028 return NULL;
1029 }
1030 return n;
1031}
struct blitterargs::@3::@4 cell
union blitterargs::@3 u
uint32_t transcolor
Definition internal.h:380
int ncvisual_blit_internal(const ncvisual *ncv, int rows, int cols, ncplane *n, const struct blitset *bset, const blitterargs *barg)
Definition visual.c:84
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_render_pixels()

ncplane * ncvisual_render_pixels ( notcurses nc,
ncvisual ncv,
const struct blitset bset,
int  placey,
int  placex,
const ncvgeom geom,
ncplane n,
uint64_t  flags,
uint32_t  transcolor,
int  pxoffy,
int  pxoffx 
)

Definition at line 1050 of file visual.c.

1053 {
1054 logdebug("pblit: rows/cols: %dx%d plane: %d/%d", geom->rcelly, geom->rcellx, ncplane_dim_y(n), ncplane_dim_x(n));
1055 const tinfo* ti = &nc->tcache;
1056 blitterargs bargs;
1057 bargs.transcolor = transcolor;
1058 bargs.begy = geom->begy;
1059 bargs.begx = geom->begx;
1060 bargs.leny = geom->leny;
1061 bargs.lenx = geom->lenx;
1062 bargs.flags = flags;
1063 bargs.u.pixel.colorregs = ti->color_registers;
1064 bargs.u.pixel.pxoffy = pxoffy;
1065 bargs.u.pixel.pxoffx = pxoffx;
1066 bargs.u.pixel.cellpxy = geom->cdimy;
1067 bargs.u.pixel.cellpxx = geom->cdimx;
1068 const ncpile* p = ncplane_pile_const(n);
1069 if(n->sprite == NULL){
1070 if((n->sprite = sprixel_alloc(n, geom->rcelly, geom->rcellx)) == NULL){
1071 return NULL;
1072 }
1073 if((n->tam = create_tam(geom->rcelly, geom->rcellx)) == NULL){
1074 return NULL;;
1075 }
1076 }else{
1077 n->sprite = sprixel_recycle(n);
1078 if(n->sprite->dimy != geom->rcelly || n->sprite->dimx != geom->rcellx){
1079 destroy_tam(n);
1080 if((n->tam = create_tam(geom->rcelly, geom->rcellx)) == NULL){
1081 return NULL;
1082 }
1083 }
1084 n->sprite->dimx = geom->rcellx;
1085 n->sprite->dimy = geom->rcelly;
1086 }
1087 bargs.u.pixel.spx = n->sprite;
1088 // FIXME need to pull off the ncpile's sprixellist if anything below fails!
1089 if(ncvisual_blit_internal(ncv, geom->rpixy, geom->rpixx, n, bset, &bargs)){
1090 return NULL;
1091 }
1092 // if we created the plane earlier, placex/placey were taken into account, and
1093 // zeroed out, thus neither of these will have any effect.
1094 if(flags & NCVISUAL_OPTION_HORALIGNED){
1095 if(placex == NCALIGN_CENTER){
1096 placex = (ncplane_dim_x(ncplane_parent_const(n)) * p->cellpxx - geom->rpixx) / 2 / p->cellpxx;
1097 }else if(placex == NCALIGN_RIGHT){
1098 placex = (ncplane_dim_x(ncplane_parent_const(n)) * p->cellpxx - geom->rpixx) / p->cellpxx;
1099 }
1100 if(placex < 0){
1101 return NULL;
1102 }
1103 }
1104 if(flags & NCVISUAL_OPTION_VERALIGNED){
1105 if(placey == NCALIGN_CENTER){
1106 placey = (ncplane_dim_y(ncplane_parent_const(n)) * p->cellpxy - geom->rpixy) / 2 / p->cellpxy;
1107 }else if(placey == NCALIGN_BOTTOM){
1108 placey = (ncplane_dim_y(ncplane_parent_const(n)) * p->cellpxy - geom->rpixy) / p->cellpxy;
1109 }
1110 if(placey < 0){
1111 return NULL;
1112 }
1113 }
1114 // ncplane_resize() hides any attached sprixel, so lift it (the sprixel) out
1115 // for a moment as we shrink the plane to fit. we keep the origin and move to
1116 // the intended location.
1117 sprixel* s = n->sprite;
1118 n->sprite = NULL;
1119//fprintf(stderr, "ABOUT TO RESIZE: yoff/xoff: %d/%d\n", placey, placex);
1120 // FIXME might need shrink down the TAM and kill unnecessary auxvecs
1121 if(ncplane_resize(n, 0, 0, s->dimy, s->dimx, placey, placex, s->dimy, s->dimx)){
1122 // if we blow up here, then we've got a TAM sized to the sprixel, rather
1123 // than the plane. running it through destroy_tam() via ncplane_destroy()
1124 // will use incorrect bounds for scrubbing said TAM. do it manually here.
1125 cleanup_tam(n->tam, geom->rcelly, geom->rcellx);
1126 free(n->tam);
1127 n->tam = NULL;
1128 sprixel_hide(bargs.u.pixel.spx);
1129 return NULL;
1130 }
1131 n->sprite = bargs.u.pixel.spx;
1132//fprintf(stderr, "RESIZED: %d/%d at %d/%d %p\n", ncplane_dim_y(n), ncplane_dim_x(n), ncplane_y(n), ncplane_x(n), n->sprite);
1133 return n;
1134}
sprixel * sprixel_recycle(ncplane *n)
Definition sprite.c:51
void sprixel_hide(sprixel *s)
Definition sprite.c:83
sprixel * sprixel_alloc(ncplane *n, int dimy, int dimx)
Definition sprite.c:117
const ncplane * ncplane_parent_const(const ncplane *n)
Definition notcurses.c:2655
int ncplane_resize(ncplane *n, int keepy, int keepx, unsigned keepleny, unsigned keeplenx, int yoff, int xoff, unsigned ylen, unsigned xlen)
Definition notcurses.c:1006
@ NCALIGN_CENTER
Definition notcurses.h:83
#define NCALIGN_BOTTOM
Definition notcurses.h:88
struct blitterargs::@3::@5 pixel
sprixel * spx
Definition internal.h:388
int colorregs
Definition internal.h:387
unsigned dimx
Definition sprite.h:146
unsigned dimy
Definition sprite.h:146
int color_registers
Definition termdesc.h:164
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_resize()

int ncvisual_resize ( ncvisual n,
int  rows,
int  cols 
)

Definition at line 982 of file visual.c.

982 {
984 return ncvisual_resize_noninterpolative(n, rows, cols);
985 }
986 if(visual_implementation->visual_resize(n, rows, cols)){
987 return -1;
988 }
989 return 0;
990}
int(* visual_resize)(struct ncvisual *ncv, unsigned rows, unsigned cols)
Definition internal.h:1812
int ncvisual_resize_noninterpolative(ncvisual *n, int rows, int cols)
Definition visual.c:992
Here is the call graph for this function:

◆ ncvisual_resize_noninterpolative()

int ncvisual_resize_noninterpolative ( ncvisual n,
int  rows,
int  cols 
)

Definition at line 992 of file visual.c.

992 {
993 size_t dstride = pad_for_image(cols * 4, cols);
994 uint32_t* r = resize_bitmap(n->data, n->pixy, n->pixx, n->rowstride,
995 rows, cols, dstride);
996 if(r == NULL){
997 return -1;
998 }
999 ncvisual_set_data(n, r, true);
1000 n->rowstride = dstride;
1001 n->pixy = rows;
1002 n->pixx = cols;
1004 return 0;
1005}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_rotate()

int ncvisual_rotate ( ncvisual ncv,
double  rads 
)

Definition at line 704 of file visual.c.

704 {
705 assert(ncv->rowstride / 4 >= ncv->pixx);
706 rads = -rads; // we're a left-handed Cartesian
707 int centy, centx;
708 ncvisual_center(ncv, &centy, &centx); // pixel center (center of 'data')
709 double stheta, ctheta; // sine, cosine
710 stheta = sin(rads);
711 ctheta = cos(rads);
712 // bounding box for real data within the ncvisual. we must only resize to
713 // accommodate real data, lest we grow without band as we rotate.
714 // see https://github.com/dankamongmen/notcurses/issues/599.
715 int bby = ncv->pixy;
716 int bbx = ncv->pixx;
717 int bboffy = 0;
718 int bboffx = 0;
719 if(ncvisual_bounding_box(ncv, &bby, &bbx, &bboffy, &bboffx) <= 0){
720 logerror("couldn't find a bounding box");
721 return -1;
722 }
723 int bbarea;
724 bbarea = rotate_bounding_box(stheta, ctheta, &bby, &bbx, &bboffy, &bboffx);
725 if(bbarea <= 0){
726 logerror("couldn't rotate the visual (%d, %d, %d, %d)", bby, bbx, bboffy, bboffx);
727 return -1;
728 }
729 int bbcentx = bbx, bbcenty = bby;
730 center_box(&bbcenty, &bbcentx);
731//fprintf(stderr, "stride: %d height: %d width: %d\n", ncv->rowstride, ncv->pixy, ncv->pixx);
732 assert(ncv->rowstride / 4 >= ncv->pixx);
733 uint32_t* data = malloc(bbarea * 4);
734 if(data == NULL){
735 return -1;
736 }
737 memset(data, 0, bbarea * 4);
738//fprintf(stderr, "bbarea: %d bby: %d bbx: %d centy: %d centx: %d bbcenty: %d bbcentx: %d\n", bbarea, bby, bbx, centy, centx, bbcenty, bbcentx);
739 for(unsigned y = 0 ; y < ncv->pixy ; ++y){
740 for(unsigned x = 0 ; x < ncv->pixx ; ++x){
741 int targx = x, targy = y;
742 rotate_point(&targy, &targx, stheta, ctheta, centy, centx);
743 if(targx > bboffx && targy > bboffy){
744 const int deconvx = targx - bboffx;
745 const int deconvy = targy - bboffy;
746 if(deconvy < bby && deconvx < bbx){
747 data[deconvy * bbx + deconvx] = ncv->data[y * (ncv->rowstride / 4) + x];
748 }
749 }
750//fprintf(stderr, "CW: %d/%d (%08x) -> %d/%d (stride: %d)\n", y, x, ncv->data[y * (ncv->rowstride / 4) + x], targy, targx, ncv->rowstride);
751//fprintf(stderr, "wrote %08x to %d (%d)\n", data[targy * ncv->pixy + targx], targy * ncv->pixy + targx, (targy * ncv->pixy + targx) * 4);
752 }
753 }
754 ncvisual_set_data(ncv, data, true);
755 ncv->pixx = bbx;
756 ncv->pixy = bby;
757 ncv->rowstride = bbx * 4;
759 return 0;
760}
int ncvisual_bounding_box(const ncvisual *ncv, int *leny, int *lenx, int *offy, int *offx)
Definition visual.c:534
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_set_yx()

int ncvisual_set_yx ( const struct ncvisual n,
unsigned  y,
unsigned  x,
uint32_t  pixel 
)

Definition at line 1259 of file visual.c.

1259 {
1260 if(y >= n->pixy){
1261 logerror("invalid coordinates %u/%u", y, x);
1262 return -1;
1263 }
1264 if(x >= n->pixx){
1265 logerror("invalid coordinates %u/%u", y, x);
1266 return -1;
1267 }
1268 n->data[y * (n->rowstride / 4) + x] = pixel;
1269 return 0;
1270}
Here is the caller graph for this function:

◆ ncvisual_simple_streamer()

int ncvisual_simple_streamer ( ncvisual ncv,
struct ncvisual_options vopts,
const struct timespec *  tspec,
void *  curry 
)

Definition at line 1238 of file visual.c.

1239 {
1240 struct ncplane* subtitle = NULL;
1241 int ret = 0;
1242 if(curry){
1243 // FIXME improve this hrmmmmm
1244 ncplane* subncp = curry;
1245 if(subncp->blist){
1246 ncplane_destroy(subncp->blist);
1247 subncp->blist = NULL;
1248 }
1249 subtitle = ncvisual_subtitle_plane(subncp, ncv);
1250 }
1251 if(notcurses_render(ncplane_notcurses(vopts->n))){
1252 return -1;
1253 }
1254 clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, tspec, NULL);
1255 ncplane_destroy(subtitle);
1256 return ret;
1257}
notcurses * ncplane_notcurses(const ncplane *n)
Definition notcurses.c:2626
struct ncplane * blist
Definition internal.h:102
ncplane * ncvisual_subtitle_plane(ncplane *parent, const ncvisual *ncv)
Definition visual.c:77
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncvisual_stream()

int ncvisual_stream ( notcurses nc,
ncvisual ncv,
float  timescale,
ncstreamcb  streamer,
const struct ncvisual_options vopts,
void *  curry 
)

Definition at line 64 of file visual.c.

66 {
68 return -1;
69 }
70 int ret = visual_implementation->visual_stream(nc, ncv, timescale, streamer, vopts, curry);
71 if(ret < 0){
72 logerror("error streaming media");
73 }
74 return ret;
75}
int(* visual_stream)(notcurses *nc, struct ncvisual *ncv, float timescale, ncstreamcb streamer, const struct ncvisual_options *vopts, void *curry)
Definition internal.h:1807
Here is the caller graph for this function:

◆ ncvisual_subtitle_plane()

ncplane * ncvisual_subtitle_plane ( ncplane parent,
const ncvisual ncv 
)

Definition at line 77 of file visual.c.

77 {
79 return NULL;
80 }
82}
ncplane *(* visual_subtitle)(ncplane *parent, const struct ncvisual *ncv)
Definition internal.h:1809
Here is the caller graph for this function:

◆ notcurses_canopen_images()

bool notcurses_canopen_images ( const notcurses *nc   __attribute__(unused))

Definition at line 1357 of file visual.c.

1357 {
1359 return false;
1360 }
1362}
Here is the caller graph for this function:

◆ notcurses_canopen_videos()

bool notcurses_canopen_videos ( const notcurses *nc   __attribute__(unused))

Definition at line 1364 of file visual.c.

1364 {
1366 return false;
1367 }
1369}
Here is the caller graph for this function:

◆ rgb_loose_to_rgba()

void * rgb_loose_to_rgba ( const void *  data,
int  rows,
int *  rowstride,
int  cols,
int  alpha 
)

Definition at line 461 of file visual.c.

461 {
462 if(*rowstride % 4){ // must be a multiple of 4 bytes
463 return NULL;
464 }
465 if(*rowstride < cols * 4){
466 return NULL;
467 }
468 uint32_t* ret = malloc(4 * cols * rows);
469 if(ret){
470 for(int y = 0 ; y < rows ; ++y){
471 for(int x = 0 ; x < cols ; ++x){
472 const uint32_t* src = (const uint32_t*)data + (*rowstride / 4) * y + x;
473 uint32_t* dst = ret + cols * y + x;
474 ncpixel_set_a(dst, alpha);
475 ncpixel_set_r(dst, ncpixel_r(*src));
476 ncpixel_set_g(dst, ncpixel_g(*src));
477 ncpixel_set_b(dst, ncpixel_b(*src));
478 }
479 }
480 }
481 *rowstride = cols * 4;
482 return ret;
483}
Here is the caller graph for this function:

◆ rgb_packed_to_rgba()

void * rgb_packed_to_rgba ( const void *  data,
int  rows,
int *  rowstride,
int  cols,
int  alpha 
)

Definition at line 485 of file visual.c.

485 {
486 if(*rowstride < cols * 3){
487 return NULL;
488 }
489 uint32_t* ret = malloc(4 * cols * rows);
490 if(ret){
491 for(int y = 0 ; y < rows ; ++y){
492 for(int x = 0 ; x < cols ; ++x){
493 const unsigned char* src = (const unsigned char*)data + *rowstride * y + x;
494 uint32_t* dst = ret + cols * y + x;
495 ncpixel_set_a(dst, alpha);
496 ncpixel_set_r(dst, src[0]);
497 ncpixel_set_g(dst, src[1]);
498 ncpixel_set_b(dst, src[2]);
499 }
500 }
501 }
502 *rowstride = cols * 4;
503 return ret;
504}
Here is the caller graph for this function:

Variable Documentation

◆ visual_implementation

ncvisual_implementation* visual_implementation = &null_visual_implementation

Definition at line 20 of file visual.c.