Work on loading images

This commit is contained in:
Kovid Goyal 2017-09-27 09:10:56 +05:30
parent 8418cc04c1
commit c567acb4e5
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 47 additions and 3 deletions

View File

@ -35,15 +35,52 @@ grman_free(GraphicsManager* self) {
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
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
grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_t *payload) {
switch(g->action) {
case 0:
case 't':
handle_add_command(self, g, payload);
break;

View File

@ -19,6 +19,7 @@ typedef struct {
typedef struct {
uint32_t gl_id, client_id, width, height;
size_t internal_id, refcnt;
uint8_t *load_buf;
} Image;

View File

@ -664,6 +664,10 @@ parse_graphics_code(Screen *screen, PyObject UNUSED *dump_callback) {
default:
break;
}
if (g.data_width > 10000 || g.data_height > 10000) {
REPORT_ERROR("Image too large");
return;
}
#define A(x) #x, g.x
#define U(x) #x, (unsigned int)(g.x)
#define I(x) #x, (int)(g.x)

View File

@ -225,8 +225,10 @@ class TestParser(BaseTest):
e(',s=1', 'Malformed graphics control block, invalid key character: 0x2c')
e('W=1', 'Malformed graphics control block, invalid key character: 0x57')
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, 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=20000', 'Image too large')
e('v=20000', 'Image too large')