Work on loading images
This commit is contained in:
parent
8418cc04c1
commit
c567acb4e5
@ -35,15 +35,52 @@ grman_free(GraphicsManager* self) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static size_t internal_id_counter = 1; */
|
static size_t internal_id_counter = 1;
|
||||||
|
|
||||||
|
static inline void*
|
||||||
|
ensure_space(void *array, size_t *capacity, size_t count, size_t item_size, bool initialize) {
|
||||||
|
if (count < *capacity) return array;
|
||||||
|
void *ans = realloc(array, (*capacity) * item_size * 2);
|
||||||
|
if (ans == NULL) fatal("Out of memory re-allocating array.");
|
||||||
|
if (initialize) {
|
||||||
|
memset(((uint8_t*)array) + ((*capacity) * item_size), 0, ((*capacity) * item_size));
|
||||||
|
}
|
||||||
|
*capacity *= 2;
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Image*
|
||||||
|
find_or_create_image(GraphicsManager *self, uint32_t id, bool *existing) {
|
||||||
|
if (id) {
|
||||||
|
for (size_t i = 0; i < self->image_count; i++) {
|
||||||
|
if (self->images[i].client_id == id) {
|
||||||
|
*existing = true;
|
||||||
|
return self->images + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*existing = false;
|
||||||
|
self->images = ensure_space(self->images, &self->images_capacity, self->image_count, sizeof(Image), true);
|
||||||
|
return self->images + self->image_count++;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_add_command(GraphicsManager UNUSED *self, const GraphicsCommand UNUSED *g, const uint8_t UNUSED *payload) {
|
handle_add_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_t UNUSED *payload) {
|
||||||
|
bool existing;
|
||||||
|
Image *img = find_or_create_image(self, g->id, &existing);
|
||||||
|
if (existing) {
|
||||||
|
free(img->load_buf); img->load_buf = NULL;
|
||||||
|
} else {
|
||||||
|
img->internal_id = internal_id_counter++;
|
||||||
|
img->client_id = g->id;
|
||||||
|
}
|
||||||
|
img->width = g->data_width; img->height = g->data_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_t *payload) {
|
grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_t *payload) {
|
||||||
switch(g->action) {
|
switch(g->action) {
|
||||||
|
case 0:
|
||||||
case 't':
|
case 't':
|
||||||
handle_add_command(self, g, payload);
|
handle_add_command(self, g, payload);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -19,6 +19,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t gl_id, client_id, width, height;
|
uint32_t gl_id, client_id, width, height;
|
||||||
size_t internal_id, refcnt;
|
size_t internal_id, refcnt;
|
||||||
|
uint8_t *load_buf;
|
||||||
} Image;
|
} Image;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -664,6 +664,10 @@ parse_graphics_code(Screen *screen, PyObject UNUSED *dump_callback) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (g.data_width > 10000 || g.data_height > 10000) {
|
||||||
|
REPORT_ERROR("Image too large");
|
||||||
|
return;
|
||||||
|
}
|
||||||
#define A(x) #x, g.x
|
#define A(x) #x, g.x
|
||||||
#define U(x) #x, (unsigned int)(g.x)
|
#define U(x) #x, (unsigned int)(g.x)
|
||||||
#define I(x) #x, (int)(g.x)
|
#define I(x) #x, (int)(g.x)
|
||||||
|
|||||||
@ -225,8 +225,10 @@ class TestParser(BaseTest):
|
|||||||
e(',s=1', 'Malformed graphics control block, invalid key character: 0x2c')
|
e(',s=1', 'Malformed graphics control block, invalid key character: 0x2c')
|
||||||
e('W=1', 'Malformed graphics control block, invalid key character: 0x57')
|
e('W=1', 'Malformed graphics control block, invalid key character: 0x57')
|
||||||
e('1=1', 'Malformed graphics control block, invalid key character: 0x31')
|
e('1=1', 'Malformed graphics control block, invalid key character: 0x31')
|
||||||
e('a=1,,w=2', 'Malformed graphics control block, invalid key character: 0x2c')
|
e('a=t,,w=2', 'Malformed graphics control block, invalid key character: 0x2c')
|
||||||
e('s', 'Malformed graphics control block, no = after key')
|
e('s', 'Malformed graphics control block, no = after key')
|
||||||
e('s=', 'Malformed graphics control block, expecting an integer value')
|
e('s=', 'Malformed graphics control block, expecting an integer value')
|
||||||
e('s==', 'Malformed graphics control block, expecting an integer value')
|
e('s==', 'Malformed graphics control block, expecting an integer value')
|
||||||
e('s=1=', 'Malformed graphics control block, expecting a comma or semi-colon after a value, found: 0x3d')
|
e('s=1=', 'Malformed graphics control block, expecting a comma or semi-colon after a value, found: 0x3d')
|
||||||
|
e('s=20000', 'Image too large')
|
||||||
|
e('v=20000', 'Image too large')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user