diff options
author | Přemysl Janouch <p.janouch@gmail.com> | 2014-10-27 18:49:21 +0100 |
---|---|---|
committer | Přemysl Janouch <p.janouch@gmail.com> | 2014-10-27 18:49:21 +0100 |
commit | 606c5f43af3b9b7a5f1484540e7455346bba31c9 (patch) | |
tree | f2edf80dcd6623fff8245c0728528de5f5eb6bef | |
parent | 5cebe379c86133cc532f66f634e94de18ca0cb54 (diff) | |
download | neetdraw-606c5f43af3b9b7a5f1484540e7455346bba31c9.tar.gz neetdraw-606c5f43af3b9b7a5f1484540e7455346bba31c9.tar.xz neetdraw-606c5f43af3b9b7a5f1484540e7455346bba31c9.zip |
Use RLE bitmap compressionlibuv
-rw-r--r-- | autistdraw.c | 44 | ||||
-rw-r--r-- | utils.c | 16 |
2 files changed, 36 insertions, 24 deletions
diff --git a/autistdraw.c b/autistdraw.c index 18ff297..41a2942 100644 --- a/autistdraw.c +++ b/autistdraw.c @@ -272,8 +272,26 @@ send_get_bitmap_response (client_t *client, app_context_t *app) msg_writer_u64 (&writer, app->bitmap_w); msg_writer_u64 (&writer, app->bitmap_h); - msg_writer_blob (&writer, app->bitmap, - app->bitmap_w * app->bitmap_h * sizeof *app->bitmap); + // Simple RLE compression + size_t size = app->bitmap_w * app->bitmap_h; + uint8_t last_value = 0, count = 0; + for (size_t i = 0; i < size; i++) + { + uint8_t value = app->bitmap[i]; + if ((count && value != last_value) || count == 0xFF) + { + msg_writer_u8 (&writer, count); + msg_writer_u8 (&writer, last_value); + count = 0; + } + count++; + last_value = value; + } + if (count) + { + msg_writer_u8 (&writer, count); + msg_writer_u8 (&writer, last_value); + } flush_writer_to_client (&writer, client); } @@ -970,17 +988,27 @@ on_server_get_bitmap (app_context_t *app, struct msg_unpacker *unpacker) || !msg_unpacker_u64 (unpacker, &h)) return; - // TODO: employ at least some RLE encoding - size_t size = w * h * sizeof *app->bitmap; + size_t size = w * h; if ((h && w > SIZE_MAX / h) || w > SIZE_MAX || h > SIZE_MAX) return; - const void *data; - if (!msg_unpacker_blob (unpacker, &data, size)) - return; + uint8_t *bitmap = xcalloc (size, sizeof *app->bitmap); + + // RLE decompression + size_t i = 0; + uint8_t len, value; + while (msg_unpacker_u8 (unpacker, &len) + && msg_unpacker_u8 (unpacker, &value)) + { + // Don't allow overflow + if (i + len > size || i + len < i) + break; + for (size_t x = 0; x < len; x++) + bitmap[i++] = value; + } free (app->bitmap); - app->bitmap = memcpy (xcalloc (1, size), data, size); + app->bitmap = bitmap; app->bitmap_x = x; app->bitmap_y = y; app->bitmap_w = w; @@ -382,16 +382,6 @@ msg_unpacker_get_available (struct msg_unpacker *self) return self->len - self->offset; } -static bool -msg_unpacker_blob (struct msg_unpacker *self, const void **data, size_t len) -{ - if (self->len - self->offset < len) - return false; - *data = self->data + self->offset; - self->offset += len; - return true; -} - #define UNPACKER_INT_BEGIN \ if (self->len - self->offset < sizeof *value) \ return false; \ @@ -446,12 +436,6 @@ msg_writer_init (struct msg_writer *self) } static void -msg_writer_blob (struct msg_writer *self, const void *data, size_t len) -{ - str_append_data (&self->buf, data, len); -} - -static void msg_writer_u8 (struct msg_writer *self, uint8_t x) { str_append_data (&self->buf, &x, 1); |