mirror of
https://github.com/tmux/tmux.git
synced 2026-09-05 21:20:45 +00:00
Use compact image references in grid cells
This commit is contained in:
6
grid.c
6
grid.c
@@ -80,7 +80,7 @@ grid_entry_image(struct grid_line *gl, struct grid_cell_entry *gce)
|
||||
gee = &gl->extddata[gce->offset];
|
||||
if (~gee->flags & GRID_FLAG_IMAGE)
|
||||
return (0);
|
||||
return (gee->image_id);
|
||||
return (image_get_id_by_grid_id(gee->image_id));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -211,7 +211,7 @@ grid_extended_cell(struct grid_line *gl, struct grid_cell_entry *gce,
|
||||
gee->us = gc->us;
|
||||
gee->link = gc->link;
|
||||
#ifdef ENABLE_IMAGES
|
||||
gee->image_id = gc->image_id;
|
||||
gee->image_id = image_get_grid_id(gc->image_id);
|
||||
gee->image_x = gc->image_x;
|
||||
gee->image_y = gc->image_y;
|
||||
#endif
|
||||
@@ -684,7 +684,7 @@ grid_get_cell1(struct grid_line *gl, u_int px, struct grid_cell *gc)
|
||||
gc->us = gee->us;
|
||||
gc->link = gee->link;
|
||||
#ifdef ENABLE_IMAGES
|
||||
gc->image_id = gee->image_id;
|
||||
gc->image_id = image_get_id_by_grid_id(gee->image_id);
|
||||
gc->image_x = gee->image_x;
|
||||
gc->image_y = gee->image_y;
|
||||
#endif
|
||||
|
||||
37
image.c
37
image.c
@@ -45,6 +45,7 @@ struct image_cell {
|
||||
/* Immutable image data and cell geometry. */
|
||||
struct image {
|
||||
u_int id;
|
||||
u_short grid_id;
|
||||
u_int references;
|
||||
u_int width;
|
||||
u_int height;
|
||||
@@ -78,6 +79,8 @@ struct image_rectangle {
|
||||
|
||||
static struct images images = RB_INITIALIZER(&images);
|
||||
static u_int image_next_id;
|
||||
static u_short image_next_grid_id;
|
||||
static struct image *image_grid_ids[USHRT_MAX + 1];
|
||||
|
||||
#define IMAGE_BACKEND_GRAPHICAL 0x1
|
||||
#define IMAGE_BACKEND_SCROLLS 0x2
|
||||
@@ -345,6 +348,7 @@ image_create(u_int width, u_int height, u_int canvas_width,
|
||||
u_int canvas_height, u_int sx, u_int sy, u_char *pixels)
|
||||
{
|
||||
struct image *im;
|
||||
u_int i;
|
||||
|
||||
if (width == 0 || height == 0 || canvas_width < width ||
|
||||
canvas_height < height || sx == 0 || sy == 0 || pixels == NULL)
|
||||
@@ -353,6 +357,16 @@ image_create(u_int width, u_int height, u_int canvas_width,
|
||||
return (NULL);
|
||||
if ((uint64_t)sx * sy > SIZE_MAX / sizeof *im->cells)
|
||||
return (NULL);
|
||||
if (sx > USHRT_MAX || sy > USHRT_MAX)
|
||||
return (NULL);
|
||||
for (i = 0; i < USHRT_MAX; i++) {
|
||||
if (++image_next_grid_id == 0)
|
||||
image_next_grid_id++;
|
||||
if (image_grid_ids[image_next_grid_id] == NULL)
|
||||
break;
|
||||
}
|
||||
if (i == USHRT_MAX)
|
||||
return (NULL);
|
||||
|
||||
im = xcalloc(1, sizeof *im);
|
||||
do {
|
||||
@@ -362,6 +376,7 @@ image_create(u_int width, u_int height, u_int canvas_width,
|
||||
} while (image_find(im->id) != NULL);
|
||||
|
||||
im->references = 1;
|
||||
im->grid_id = image_next_grid_id;
|
||||
im->width = width;
|
||||
im->height = height;
|
||||
im->canvas_width = canvas_width;
|
||||
@@ -373,12 +388,33 @@ image_create(u_int width, u_int height, u_int canvas_width,
|
||||
im->pixels = pixels;
|
||||
|
||||
RB_INSERT(images, &images, im);
|
||||
image_grid_ids[im->grid_id] = im;
|
||||
log_debug("%s: image %u is %ux%u pixels on %ux%u canvas, "
|
||||
"%ux%u cells", __func__, im->id, width, height, canvas_width,
|
||||
canvas_height, sx, sy);
|
||||
return (im);
|
||||
}
|
||||
|
||||
u_short
|
||||
image_get_grid_id(u_int id)
|
||||
{
|
||||
struct image *im = image_find(id);
|
||||
|
||||
if (im == NULL)
|
||||
return (0);
|
||||
return (im->grid_id);
|
||||
}
|
||||
|
||||
u_int
|
||||
image_get_id_by_grid_id(u_short grid_id)
|
||||
{
|
||||
struct image *im;
|
||||
|
||||
if (grid_id == 0 || (im = image_grid_ids[grid_id]) == NULL)
|
||||
return (0);
|
||||
return (im->id);
|
||||
}
|
||||
|
||||
void
|
||||
image_ref(u_int id)
|
||||
{
|
||||
@@ -403,6 +439,7 @@ image_free(u_int id)
|
||||
|
||||
log_debug("%s: freeing image %u", __func__, id);
|
||||
RB_REMOVE(images, &images, im);
|
||||
image_grid_ids[im->grid_id] = NULL;
|
||||
free(im->pixels);
|
||||
if (im->sixel != NULL)
|
||||
sixel_free(im->sixel);
|
||||
|
||||
8
tmux.h
8
tmux.h
@@ -887,9 +887,9 @@ struct grid_extd_entry {
|
||||
int us;
|
||||
u_int link;
|
||||
#ifdef ENABLE_IMAGES
|
||||
u_int image_id;
|
||||
u_int image_x;
|
||||
u_int image_y;
|
||||
u_short image_id;
|
||||
u_short image_x;
|
||||
u_short image_y;
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
@@ -4242,6 +4242,8 @@ struct image *image_create(u_int, u_int, u_int, u_int, u_int, u_int,
|
||||
u_char *);
|
||||
struct image *image_find(u_int);
|
||||
u_int image_get_id(const struct image *);
|
||||
u_short image_get_grid_id(u_int);
|
||||
u_int image_get_id_by_grid_id(u_short);
|
||||
void image_get_dimensions(const struct image *, u_int *, u_int *);
|
||||
void image_get_canvas_dimensions(const struct image *, u_int *, u_int *);
|
||||
void image_get_cell_dimensions(const struct image *, u_int *, u_int *);
|
||||
|
||||
Reference in New Issue
Block a user