aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2014-10-27 18:49:21 +0100
committerPřemysl Janouch <p.janouch@gmail.com>2014-10-27 18:49:21 +0100
commit606c5f43af3b9b7a5f1484540e7455346bba31c9 (patch)
treef2edf80dcd6623fff8245c0728528de5f5eb6bef
parent5cebe379c86133cc532f66f634e94de18ca0cb54 (diff)
downloadautistdraw-libuv.tar.gz
autistdraw-libuv.tar.xz
autistdraw-libuv.zip
Use RLE bitmap compressionlibuv
-rw-r--r--autistdraw.c44
-rw-r--r--utils.c16
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;
diff --git a/utils.c b/utils.c
index f7c8fad..df16559 100644
--- a/utils.c
+++ b/utils.c
@@ -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);