Notcurses 3.0.13
a blingful library for TUIs and character graphics
Loading...
Searching...
No Matches
kitty.c File Reference
#include "internal.h"
#include "base64.h"
#include <zlib.h>
Include dependency graph for kitty.c:

Go to the source code of this file.

Macros

#define RGBA_MAXLEN   768
 
#define TRINULLALPHA   "AAAAAAAAAAAAAAAA"
 
#define UNUMNULLALPHA   "AAAAAA=="
 
#define DUONULLALPHA   "AAAAAAAAAAA="
 

Functions

int kitty_rebuild (sprixel *s, int ycell, int xcell, uint8_t *auxvec)
 
uint8_t * kitty_trans_auxvec (const ncpile *p)
 
int kitty_wipe_animation (sprixel *s, int ycell, int xcell)
 
int kitty_wipe_selfref (sprixel *s, int ycell, int xcell)
 
sprixelkitty_recycle (ncplane *n)
 
int kitty_wipe (sprixel *s, int ycell, int xcell)
 
int kitty_commit (fbuf *f, sprixel *s, unsigned noscroll)
 
int kitty_rebuild_selfref (sprixel *s, int ycell, int xcell, uint8_t *auxvec)
 
int kitty_rebuild_animation (sprixel *s, int ycell, int xcell, uint8_t *auxvec)
 
int kitty_blit (ncplane *n, int linesize, const void *data, int leny, int lenx, const blitterargs *bargs)
 
int kitty_blit_animated (ncplane *n, int linesize, const void *data, int leny, int lenx, const blitterargs *bargs)
 
int kitty_blit_selfref (ncplane *n, int linesize, const void *data, int leny, int lenx, const blitterargs *bargs)
 
int kitty_remove (int id, fbuf *f)
 
int kitty_scrub (const ncpile *p, sprixel *s)
 
int kitty_draw (const tinfo *ti, const ncpile *p, sprixel *s, fbuf *f, int yoff, int xoff)
 
int kitty_move (sprixel *s, fbuf *f, unsigned noscroll, int yoff, int xoff)
 
int kitty_clear_all (fbuf *f)
 

Macro Definition Documentation

◆ DUONULLALPHA

#define DUONULLALPHA   "AAAAAAAAAAA="

◆ RGBA_MAXLEN

#define RGBA_MAXLEN   768

Definition at line 216 of file kitty.c.

◆ TRINULLALPHA

#define TRINULLALPHA   "AAAAAAAAAAAAAAAA"

◆ UNUMNULLALPHA

#define UNUMNULLALPHA   "AAAAAA=="

Function Documentation

◆ kitty_blit()

int kitty_blit ( ncplane n,
int  linesize,
const void *  data,
int  leny,
int  lenx,
const blitterargs bargs 
)

Definition at line 1112 of file kitty.c.

1113 {
1114 return kitty_blit_core(n, linesize, data, leny, lenx, bargs,
1116}
vopts n
Definition notcurses.h:3502
@ NCPIXEL_KITTY_STATIC
Definition notcurses.h:1680

◆ kitty_blit_animated()

int kitty_blit_animated ( ncplane n,
int  linesize,
const void *  data,
int  leny,
int  lenx,
const blitterargs bargs 
)

Definition at line 1118 of file kitty.c.

1119 {
1120 return kitty_blit_core(n, linesize, data, leny, lenx, bargs,
1122}
@ NCPIXEL_KITTY_ANIMATED
Definition notcurses.h:1685

◆ kitty_blit_selfref()

int kitty_blit_selfref ( ncplane n,
int  linesize,
const void *  data,
int  leny,
int  lenx,
const blitterargs bargs 
)

Definition at line 1124 of file kitty.c.

1125 {
1126 return kitty_blit_core(n, linesize, data, leny, lenx, bargs,
1128}
@ NCPIXEL_KITTY_SELFREF
Definition notcurses.h:1689

◆ kitty_clear_all()

int kitty_clear_all ( fbuf f)

Definition at line 1210 of file kitty.c.

1210 {
1211//fprintf(stderr, "KITTY UNIVERSAL ERASE\n");
1212 if(fbuf_putn(f, "\x1b_Ga=d,q=2\x1b\\", 12) < 0){
1213 return -1;
1214 }
1215 return 0;
1216}

◆ kitty_commit()

int kitty_commit ( fbuf f,
sprixel s,
unsigned  noscroll 
)

Definition at line 534 of file kitty.c.

534 {
535 loginfo("committing Kitty graphic id %u", s->id);
536 int i;
537 if(s->pxoffx || s->pxoffy){
538 i = fbuf_printf(f, "\e_Ga=p,i=%u,p=1,X=%u,Y=%u%s,q=2\e\\", s->id,
539 s->pxoffx, s->pxoffy, noscroll ? ",C=1" : "");
540 }else{
541 i = fbuf_printf(f, "\e_Ga=p,i=%u,p=1,q=2%s\e\\", s->id, noscroll ? ",C=1" : "");
542 }
543 if(i < 0){
544 return -1;
545 }
547 return 0;
548}
#define loginfo(fmt,...)
Definition logging.h:42
@ SPRIXEL_QUIESCENT
Definition sprite.h:21
int pxoffx
Definition sprite.h:154
int pxoffy
Definition sprite.h:154
uint32_t id
Definition sprite.h:139
sprixel_e invalidated
Definition sprite.h:143

◆ kitty_draw()

int kitty_draw ( const tinfo ti,
const ncpile p,
sprixel s,
fbuf f,
int  yoff,
int  xoff 
)

Definition at line 1170 of file kitty.c.

1171 {
1172 (void)ti;
1173 (void)p;
1174 bool animated = false;
1175 if(s->animating){ // active animation
1176 s->animating = false;
1177 animated = true;
1178 }
1179 int ret = s->glyph.used;
1180 logdebug("dumping %" PRIu64 "b for %u at %d %d", s->glyph.used, s->id, yoff, xoff);
1181 if(ret){
1182 if(fbuf_putn(f, s->glyph.buf, s->glyph.used) < 0){
1183 ret = -1;
1184 }
1185 }
1186 if(animated){
1187 fbuf_free(&s->glyph);
1188 }
1190 return ret;
1191}
#define logdebug(fmt,...)
Definition logging.h:52
@ SPRIXEL_LOADED
Definition sprite.h:23
char * buf
Definition fbuf.h:28
uint64_t used
Definition fbuf.h:27
bool animating
Definition sprite.h:159
fbuf glyph
Definition sprite.h:138

◆ kitty_move()

int kitty_move ( sprixel s,
fbuf f,
unsigned  noscroll,
int  yoff,
int  xoff 
)

Definition at line 1194 of file kitty.c.

1194 {
1195 const int targy = s->n->absy;
1196 const int targx = s->n->absx;
1197 logdebug("moving %u to %d %d", s->id, targy, targx);
1198 int ret = 0;
1199 if(goto_location(ncplane_notcurses(s->n), f, targy + yoff, targx + xoff, s->n)){
1200 ret = -1;
1201 }else if(fbuf_printf(f, "\e_Ga=p,i=%d,p=1,q=2%s\e\\", s->id,
1202 noscroll ? ",C=1" : "") < 0){
1203 ret = -1;
1204 }
1206 return ret;
1207}
notcurses * ncplane_notcurses(const ncplane *n)
Definition notcurses.c:2626
int absy
Definition internal.h:83
int absx
Definition internal.h:83
struct ncplane * n
Definition sprite.h:142
Here is the call graph for this function:

◆ kitty_rebuild()

int kitty_rebuild ( sprixel s,
int  ycell,
int  xcell,
uint8_t *  auxvec 
)

Definition at line 219 of file kitty.c.

219 {
220 const int totalpixels = s->pixy * s->pixx;
221 const int xpixels = ncplane_pile(s->n)->cellpxx;
222 const int ypixels = ncplane_pile(s->n)->cellpxy;
223 int targx = xpixels;
224 if((xcell + 1) * xpixels > s->pixx){
225 targx = s->pixx - xcell * xpixels;
226 }
227 int targy = ypixels;
228 if((ycell + 1) * ypixels > s->pixy){
229 targy = s->pixy - ycell * ypixels;
230 }
231 char* c = (char*)s->glyph.buf + s->parse_start;
232 int nextpixel = (s->pixx * ycell * ypixels) + (xpixels * xcell);
233 int thisrow = targx;
234 int chunkedhandled = 0;
236 const int chunks = totalpixels / RGBA_MAXLEN + !!(totalpixels % RGBA_MAXLEN);
237 int auxvecidx = 0;
238 while(targy && chunkedhandled < chunks){ // need to null out |targy| rows of |targx| pixels, track with |thisrow|
239 int inchunk = totalpixels - chunkedhandled * RGBA_MAXLEN;
240 if(inchunk > RGBA_MAXLEN){
241 inchunk = RGBA_MAXLEN;
242 }
243 const int curpixel = chunkedhandled * RGBA_MAXLEN;
244 // a full chunk is 4096 + 2 + 7 (5005)
245 while(nextpixel - curpixel < RGBA_MAXLEN && thisrow){
246 // our next pixel is within this chunk. find the pixel offset of the
247 // first pixel (within the chunk).
248 int pixoffset = nextpixel - curpixel;
249 int triples = pixoffset / 3;
250 int tripbytes = triples * 16;
251 int tripskip = pixoffset - triples * 3;
252 // we start within a 16-byte chunk |tripbytes| into the chunk. determine
253 // the number of bits.
254//fprintf(stderr, "pixoffset: %d next: %d tripbytes: %d tripskip: %d thisrow: %d\n", pixoffset, nextpixel, tripbytes, tripskip, thisrow);
255 // the maximum number of pixels we can convert is the minimum of the
256 // pixels remaining in the target row, and the pixels left in the chunk.
257//fprintf(stderr, "inchunk: %d total: %d triples: %d\n", inchunk, totalpixels, triples);
258 int chomped = kitty_restore(c + tripbytes, tripskip, thisrow,
259 inchunk - triples * 3, auxvec + auxvecidx,
260 &state);
261 assert(chomped >= 0);
262 auxvecidx += chomped;
263 thisrow -= chomped;
264//fprintf(stderr, "POSTCHIMP CHOMP: %d pixoffset: %d next: %d tripbytes: %d tripskip: %d thisrow: %d\n", chomped, pixoffset, nextpixel, tripbytes, tripskip, thisrow);
265 if(thisrow == 0){
266//fprintf(stderr, "CLEARED ROW, TARGY: %d\n", targy - 1);
267 if(--targy == 0){
268 s->n->tam[s->dimx * ycell + xcell].state = state;
270 return 1;
271 }
272 thisrow = targx;
273//fprintf(stderr, "BUMP IT: %d %d %d %d\n", nextpixel, s->pixx, targx, chomped);
274 nextpixel += s->pixx - targx + chomped;
275 }else{
276 nextpixel += chomped;
277 }
278 }
279 c += RGBA_MAXLEN * 4 * 4 / 3; // 4bpp * 4/3 for base64, 4096b per chunk
280 c += 8; // new chunk header
281 ++chunkedhandled;
282//fprintf(stderr, "LOOKING NOW AT %u [%s]\n", c - s->glyph, c);
283 while(*c != ';'){
284 ++c;
285 }
286 ++c;
287 }
288 return -1;
289}
assert(false)
const nccell * c
Definition egcpool.h:296
#define RGBA_MAXLEN
Definition kitty.c:216
sprixcell_e
Definition sprite.h:114
@ SPRIXCELL_OPAQUE_KITTY
Definition sprite.h:117
@ SPRIXEL_INVALIDATED
Definition sprite.h:24
tament * tam
Definition internal.h:106
int parse_start
Definition sprite.h:153
unsigned dimx
Definition sprite.h:146
int pixx
Definition sprite.h:147
int pixy
Definition sprite.h:147
sprixcell_e state
Definition sprite.h:127
Here is the call graph for this function:

◆ kitty_rebuild_animation()

int kitty_rebuild_animation ( sprixel s,
int  ycell,
int  xcell,
uint8_t *  auxvec 
)

Definition at line 972 of file kitty.c.

972 {
973 logdebug("rebuilding sprixel %u %d at %d/%d", s->id, s->invalidated, ycell, xcell);
974 if(init_sprixel_animation(s)){
975 return -1;
976 }
977 fbuf* f = &s->glyph;
978 const int cellpxy = ncplane_pile(s->n)->cellpxy;
979 const int cellpxx = ncplane_pile(s->n)->cellpxx;
980 const int ystart = ycell * cellpxy;
981 const int xstart = xcell * cellpxx;
982 const int xlen = xstart + cellpxx > s->pixx ? s->pixx - xstart : cellpxx;
983 const int ylen = ystart + cellpxy > s->pixy ? s->pixy - ystart : cellpxy;
984 const int linesize = xlen * 4;
985 const int total = xlen * ylen;
986 const int tyx = xcell + ycell * s->dimx;
987 int chunks = (total + (RGBA_MAXLEN - 1)) / RGBA_MAXLEN;
988 int totalout = 0; // total pixels of payload out
989 int y = 0; // position within source image (pixels)
990 int x = 0;
991 int targetout = 0; // number of pixels expected out after this chunk
992//fprintf(stderr, "total: %d chunks = %d, s=%d,v=%d\n", total, chunks, lenx, leny);
993 // FIXME this ought be factored out and shared with write_kitty_data()
994 logdebug("placing %d/%d at %d/%d", ylen, xlen, ycell * cellpxy, xcell * cellpxx);
995 while(chunks--){
996 if(totalout == 0){
997 const int c = kitty_anim_auxvec_blitsource_p(s, auxvec) ? 2 : 1;
998 const int r = kitty_anim_auxvec_blitsource_p(s, auxvec) ? 1 : 2;
999 if(fbuf_printf(f, "\e_Ga=f,x=%d,y=%d,s=%d,v=%d,i=%d,X=1,c=%d,r=%d,%s;",
1000 xcell * cellpxx, ycell * cellpxy, xlen, ylen,
1001 s->id, c, r, chunks ? "m=1" : "q=2") < 0){
1002 return -1;
1003 }
1004 }else{
1005 if(fbuf_putn(f, "\x1b_G", 3) < 0){
1006 return -1;
1007 }
1008 if(!chunks){
1009 if(fbuf_putn(f, "q=2,", 4) < 0){
1010 return -1;
1011 }
1012 }
1013 if(fbuf_putn(f, "m=", 2) < 0){
1014 return -1;
1015 }
1016 if(fbuf_putint(f, chunks ? 1 : 0) < 0){
1017 return -1;
1018 }
1019 if(fbuf_putc(f, ';') != 1){
1020 return -1;
1021 }
1022 }
1023 if((targetout += RGBA_MAXLEN) > total){
1024 targetout = total;
1025 }
1026 while(totalout < targetout){
1027 int encodeable = targetout - totalout;
1028 if(encodeable > 3){
1029 encodeable = 3;
1030 }
1031 uint32_t source[3]; // we encode up to 3 pixels at a time
1032 bool wipe[3];
1033 for(int e = 0 ; e < encodeable ; ++e){
1034 if(x == xlen){
1035 x = 0;
1036 ++y;
1037 }
1038 const uint32_t* line = (const uint32_t*)(auxvec + linesize * y);
1039 source[e] = line[x];
1040//fprintf(stderr, "%u/%u/%u -> %c%c%c%c %u %u %u %u\n", r, g, b, b64[0], b64[1], b64[2], b64[3], b64[0], b64[1], b64[2], b64[3]);
1041//fprintf(stderr, "Tyx: %d y: %d (%d) * %d x: %d (%d) state %d %p\n", tyx, y, y / cdimy, cols, x, x / cdimx, tam[tyx].state, tam[tyx].auxvector);
1042 wipe[e] = 0;
1043 if(rgba_trans_p(source[e], 0)){
1044 if(x % cellpxx == 0 && y % cellpxy == 0){
1045 s->n->tam[tyx].state = SPRIXCELL_TRANSPARENT;
1046 }else if(s->n->tam[tyx].state == SPRIXCELL_OPAQUE_KITTY){
1047 s->n->tam[tyx].state = SPRIXCELL_MIXED_KITTY;
1048 }
1049 }else{
1050 if(x % cellpxx == 0 && y % cellpxy == 0){
1051 s->n->tam[tyx].state = SPRIXCELL_OPAQUE_KITTY;
1052 }else if(s->n->tam[tyx].state == SPRIXCELL_TRANSPARENT){
1053 s->n->tam[tyx].state = SPRIXCELL_MIXED_KITTY;
1054 }
1055 }
1056 ++x;
1057 }
1058 totalout += encodeable;
1059 char out[17];
1060 base64_rgba3(source, encodeable, out, wipe, 0);
1061 if(fbuf_puts(f, out) < 0){
1062 return -1;
1063 }
1064 }
1065 if(fbuf_putn(f, "\x1b\\", 2) < 0){
1066 return -1;
1067 }
1068 }
1069//fprintf(stderr, "EMERGED WITH TAM STATE %d\n", s->n->tam[tyx].state);
1071 return 0;
1072}
API int API int API int uint64_t uint64_t uint64_t uint64_t unsigned unsigned xlen
Definition direct.h:217
API int API int API int uint64_t uint64_t uint64_t uint64_t unsigned ylen
Definition direct.h:217
int r
Definition fbuf.h:226
int y
Definition notcurses.h:1905
int int x
Definition notcurses.h:1905
@ SPRIXCELL_TRANSPARENT
Definition sprite.h:115
@ SPRIXCELL_MIXED_KITTY
Definition sprite.h:119
Definition fbuf.h:25
static escape_e e
Definition termdesc.h:224

◆ kitty_rebuild_selfref()

int kitty_rebuild_selfref ( sprixel s,
int  ycell,
int  xcell,
uint8_t *  auxvec 
)

Definition at line 950 of file kitty.c.

950 {
951 if(init_sprixel_animation(s)){
952 return -1;
953 }
954 fbuf* f = &s->glyph;
955 const int cellpxy = ncplane_pile(s->n)->cellpxy;
956 const int cellpxx = ncplane_pile(s->n)->cellpxx;
957 const int ystart = ycell * cellpxy;
958 const int xstart = xcell * cellpxx;
959 const int xlen = xstart + cellpxx > s->pixx ? s->pixx - xstart : cellpxx;
960 const int ylen = ystart + cellpxy > s->pixy ? s->pixy - ystart : cellpxy;
961 logdebug("rematerializing %u at %d/%d (%dx%d)", s->id, ycell, xcell, ylen, xlen);
962 fbuf_printf(f, "\e_Ga=c,x=%d,y=%d,X=%d,Y=%d,w=%d,h=%d,i=%d,r=1,c=2,q=2;\x1b\\",
963 xcell * cellpxx, ycell * cellpxy,
964 xcell * cellpxx, ycell * cellpxy,
965 xlen, ylen, s->id);
966 const int tyx = xcell + ycell * s->dimx;
967 memcpy(&s->n->tam[tyx].state, auxvec, sizeof(s->n->tam[tyx].state));
969 return 0;
970}

◆ kitty_recycle()

sprixel * kitty_recycle ( ncplane n)

Definition at line 427 of file kitty.c.

427 {
428 assert(n->sprite);
429 sprixel* hides = n->sprite;
430 int dimy = hides->dimy;
431 int dimx = hides->dimx;
432 sprixel_hide(hides);
433 return sprixel_alloc(n, dimy, dimx);
434}
void sprixel_hide(sprixel *s)
Definition sprite.c:83
sprixel * sprixel_alloc(ncplane *n, int dimy, int dimx)
Definition sprite.c:117
unsigned dimy
Definition sprite.h:146
Here is the call graph for this function:

◆ kitty_remove()

int kitty_remove ( int  id,
fbuf f 
)

Definition at line 1130 of file kitty.c.

1130 {
1131 loginfo("removing graphic %u", id);
1132 if(fbuf_printf(f, "\e_Ga=d,d=I,i=%d\e\\", id) < 0){
1133 return -1;
1134 }
1135 return 0;
1136}

◆ kitty_scrub()

int kitty_scrub ( const ncpile p,
sprixel s 
)

Definition at line 1139 of file kitty.c.

1139 {
1140//fprintf(stderr, "FROM: %d/%d state: %d s->n: %p\n", s->movedfromy, s->movedfromx, s->invalidated, s->n);
1141 for(unsigned yy = s->movedfromy ; yy < s->movedfromy + s->dimy && yy < p->dimy ; ++yy){
1142 for(unsigned xx = s->movedfromx ; xx < s->movedfromx + s->dimx && xx < p->dimx ; ++xx){
1143 const int ridx = yy * p->dimx + xx;
1144 assert(0 <= ridx);
1145 struct crender *r = &p->crender[ridx];
1146 if(!r->sprixel){
1147 if(s->n){
1148//fprintf(stderr, "CHECKING %d/%d\n", yy - s->movedfromy, xx - s->movedfromx);
1149 sprixcell_e state = sprixel_state(s, yy - s->movedfromy + s->n->absy,
1150 xx - s->movedfromx + s->n->absx);
1151 if(state == SPRIXCELL_OPAQUE_KITTY){
1152 r->s.damaged = 1;
1153 }else if(s->invalidated == SPRIXEL_MOVED){
1154 // ideally, we wouldn't damage our annihilated sprixcells, but if
1155 // we're being annihilated only during this cycle, we need to go
1156 // ahead and damage it.
1157 r->s.damaged = 1;
1158 }
1159 }else{
1160 // need this to damage cells underneath a sprixel we're removing
1161 r->s.damaged = 1;
1162 }
1163 }
1164 }
1165 }
1166 return 0;
1167}
@ SPRIXEL_MOVED
Definition sprite.h:26
struct crender::@2 s
const ncplane * p
Definition internal.h:267
unsigned dimx
Definition internal.h:325
unsigned dimy
Definition internal.h:325
int movedfromx
Definition sprite.h:151
int movedfromy
Definition sprite.h:150
Here is the call graph for this function:

◆ kitty_trans_auxvec()

uint8_t * kitty_trans_auxvec ( const ncpile p)

Definition at line 342 of file kitty.c.

342 {
343 const size_t slen = p->cellpxy * p->cellpxx;
344 uint8_t* a = malloc(slen);
345 if(a){
346 memset(a, 0, slen);
347 }
348 return a;
349}
unsigned cellpxx
Definition internal.h:326
unsigned cellpxy
Definition internal.h:326

◆ kitty_wipe()

int kitty_wipe ( sprixel s,
int  ycell,
int  xcell 
)

Definition at line 448 of file kitty.c.

448 {
449//fprintf(stderr, "NEW WIPE %d %d/%d\n", s->id, ycell, xcell);
450 uint8_t* auxvec = kitty_auxiliary_vector(s);
451 if(auxvec == NULL){
452 return -1;
453 }
454 const int totalpixels = s->pixy * s->pixx;
455 const int xpixels = ncplane_pile(s->n)->cellpxx;
456 const int ypixels = ncplane_pile(s->n)->cellpxy;
457 // if the cell is on the right or bottom borders, it might only be partially
458 // filled by actual graphic data, and we need to cap our target area.
459 int targx = xpixels;
460 if((xcell + 1) * xpixels > s->pixx){
461 targx = s->pixx - xcell * xpixels;
462 }
463 int targy = ypixels;
464 if((ycell + 1) * ypixels > s->pixy){
465 targy = s->pixy - ycell * ypixels;
466 }
467 char* c = (char*)s->glyph.buf + s->parse_start;
468//fprintf(stderr, "TARGET AREA: %d x %d @ %dx%d of %d/%d (%d/%d) len %zu\n", targy, targx, ycell, xcell, s->dimy, s->dimx, s->pixy, s->pixx, strlen(c));
469 // every pixel was 4 source bytes, 32 bits, 6.33 base64 bytes. every 3 input pixels is
470 // 12 bytes (96 bits), an even 16 base64 bytes. there is chunking to worry about. there
471 // are up to 768 pixels in a chunk.
472 int nextpixel = (s->pixx * ycell * ypixels) + (xpixels * xcell);
473 int thisrow = targx;
474 int chunkedhandled = 0;
475 const int chunks = totalpixels / RGBA_MAXLEN + !!(totalpixels % RGBA_MAXLEN);
476 int auxvecidx = 0;
477 while(targy && chunkedhandled < chunks){ // need to null out |targy| rows of |targx| pixels, track with |thisrow|
478//fprintf(stderr, "PLUCKING FROM [%s]\n", c);
479 int inchunk = totalpixels - chunkedhandled * RGBA_MAXLEN;
480 if(inchunk > RGBA_MAXLEN){
481 inchunk = RGBA_MAXLEN;
482 }
483 const int curpixel = chunkedhandled * RGBA_MAXLEN;
484 // a full chunk is 4096 + 2 + 7 (5005)
485 while(nextpixel - curpixel < RGBA_MAXLEN && thisrow){
486 // our next pixel is within this chunk. find the pixel offset of the
487 // first pixel (within the chunk).
488 int pixoffset = nextpixel - curpixel;
489 int triples = pixoffset / 3;
490 int tripbytes = triples * 16;
491 // we start within a 16-byte chunk |tripbytes| into the chunk. determine
492 // the number of bits.
493 int tripskip = pixoffset - triples * 3;
494//fprintf(stderr, "pixoffset: %d next: %d tripbytes: %d tripskip: %d thisrow: %d\n", pixoffset, nextpixel, tripbytes, tripskip, thisrow);
495 // the maximum number of pixels we can convert is the minimum of the
496 // pixels remaining in the target row, and the pixels left in the chunk.
497//fprintf(stderr, "inchunk: %d total: %d triples: %d\n", inchunk, totalpixels, triples);
498//fprintf(stderr, "PRECHOMP: [%.16s]\n", c + tripbytes);
499 int chomped = kitty_null(c + tripbytes, tripskip, thisrow,
500 inchunk - triples * 3, auxvec + auxvecidx);
501//fprintf(stderr, "POSTCHOMP: [%.16s]\n", c + tripbytes);
502 assert(chomped >= 0);
503 auxvecidx += chomped;
504 assert(auxvecidx <= ypixels * xpixels);
505 thisrow -= chomped;
506//fprintf(stderr, "POSTCHIMP CHOMP: %d pixoffset: %d next: %d tripbytes: %d tripskip: %d thisrow: %d\n", chomped, pixoffset, nextpixel, tripbytes, tripskip, thisrow);
507 if(thisrow == 0){
508//fprintf(stderr, "CLEARED ROW, TARGY: %d\n", targy - 1);
509 if(--targy == 0){
510 s->n->tam[s->dimx * ycell + xcell].auxvector = auxvec;
512 return 1;
513 }
514 thisrow = targx;
515//fprintf(stderr, "BUMP IT: %d %d %d %d\n", nextpixel, s->pixx, targx, chomped);
516 nextpixel += s->pixx - targx + chomped;
517 }else{
518 nextpixel += chomped;
519 }
520 }
521 c += RGBA_MAXLEN * 4 * 4 / 3; // 4bpp * 4/3 for base64, 4096b per chunk
522 c += 8; // new chunk header
523 ++chunkedhandled;
524//fprintf(stderr, "LOOKING NOW AT %u [%s]\n", c - s->glyph, c);
525 while(*c != ';'){
526 ++c;
527 }
528 ++c;
529 }
530 free(auxvec);
531 return -1;
532}
free(duplicated)
void * auxvector
Definition sprite.h:128
return NULL
Definition termdesc.h:229
Here is the call graph for this function:

◆ kitty_wipe_animation()

int kitty_wipe_animation ( sprixel s,
int  ycell,
int  xcell 
)

Definition at line 394 of file kitty.c.

394 {
395 logdebug("wiping sprixel %u at %d/%d", s->id, ycell, xcell);
396 if(init_sprixel_animation(s)){
397 return -1;
398 }
399 fbuf* f = &s->glyph;
400 if(kitty_blit_wipe_selfref(s, f, ycell, xcell) < 0){
401 return -1;
402 }
403 int tamidx = ycell * s->dimx + xcell;
404 uint8_t* auxvec = s->n->tam[tamidx].auxvector;
405 auxvec[ncplane_pile(s->n)->cellpxx * ncplane_pile(s->n)->cellpxy * 4] = 0;
407 return 1;
408}

◆ kitty_wipe_selfref()

int kitty_wipe_selfref ( sprixel s,
int  ycell,
int  xcell 
)

Definition at line 410 of file kitty.c.

410 {
411 if(init_sprixel_animation(s)){
412 return -1;
413 }
414 const int tyx = xcell + ycell * s->dimx;
415 int state = s->n->tam[tyx].state;
416 void* auxvec = s->n->tam[tyx].auxvector;
417 logdebug("wiping sprixel %u at %d/%d auxvec: %p state: %d", s->id, ycell, xcell, auxvec, state);
418 fbuf* f = &s->glyph;
419 if(kitty_blit_wipe_selfref(s, f, ycell, xcell)){
420 return -1;
421 }
423 memcpy(auxvec, &state, sizeof(state));
424 return 1;
425}