From 33f2264bcdd0c79b1ab8f2af33eae7b9b9f1333c Mon Sep 17 00:00:00 2001 From: Pascal Terjan Date: Tue, 19 May 2009 12:46:34 +0000 Subject: [PATCH] Import/export dirty rectangles --- caca/codec/export.c | 25 +++++++++++++------ caca/codec/import.c | 60 +++++++++++++++++++++++++++++---------------- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/caca/codec/export.c b/caca/codec/export.c index 6fbc740..cc6a5b4 100644 --- a/caca/codec/export.c +++ b/caca/codec/export.c @@ -162,26 +162,37 @@ char const * const * caca_get_export_list(void) static void *export_caca(caca_canvas_t const *cv, size_t *bytes) { char *data, *cur; - int f, n; + int f, i, n; - /* 52 bytes for the header: + /* at least 72 bytes for the header: * - 4 bytes for "\xCA\xCA" + "CV" - * - 16 bytes for the canvas header - * - 32 bytes for the frame info + * - 20 bytes for the canvas header + * - 16 bytes for each dirty rectangle info + * - 32 bytes for each frame info * 8 bytes for each character cell */ - *bytes = 20 + (32 + 8 * cv->width * cv->height) * cv->framecount; + *bytes = 24 + 16 * cv->ndirty + (32 + 8 * cv->width * cv->height) * cv->framecount; cur = data = malloc(*bytes); /* magic */ cur += sprintf(cur, "%s", "\xCA\xCA" "CV"); /* canvas_header */ - cur += sprintu32(cur, 16 + 32 * cv->framecount); + cur += sprintu32(cur, 20 + 16 * cv->ndirty + 32 * cv->framecount); cur += sprintu32(cur, cv->width * cv->height * 8 * cv->framecount); - cur += sprintu16(cur, 0x0001); + cur += sprintu16(cur, 0x0002); + cur += sprintu32(cur, cv->ndirty); cur += sprintu32(cur, cv->framecount); cur += sprintu16(cur, 0x0000); + /* dirty rectangles info */ + for(i = 0; i < cv->ndirty; i++) + { + cur += sprintu32(cur, cv->dirty_xmin); + cur += sprintu32(cur, cv->dirty_ymin); + cur += sprintu32(cur, cv->dirty_xmax); + cur += sprintu32(cur, cv->dirty_ymax); + } + /* frame_info */ for(f = 0; f < cv->framecount; f++) { diff --git a/caca/codec/import.c b/caca/codec/import.c index 2531975..690cbd8 100644 --- a/caca/codec/import.c +++ b/caca/codec/import.c @@ -223,11 +223,12 @@ static ssize_t import_caca(caca_canvas_t *cv, void const *data, size_t size) { uint8_t const *buf = (uint8_t const *)data; size_t control_size, data_size, expected_size; - unsigned int frames, f, n, offset; + unsigned int frames, f, i, n, offset, ndirty; uint16_t version, flags; int32_t xmin = 0, ymin = 0, xmax = 0, ymax = 0; + int dirty_xmin, dirty_ymin, dirty_xmax, dirty_ymax; - if(size < 20) + if(size < 36) return 0; if(buf[0] != 0xca || buf[1] != 0xca || buf[2] != 'C' || buf[3] != 'V') @@ -239,33 +240,50 @@ static ssize_t import_caca(caca_canvas_t *cv, void const *data, size_t size) control_size = sscanu32(buf + 4); data_size = sscanu32(buf + 8); version = sscanu16(buf + 12); - frames = sscanu32(buf + 14); - flags = sscanu16(buf + 18); + ndirty = sscanu32(buf + 14); + frames = sscanu32(buf + 18); + flags = sscanu16(buf + 22); + + if(version != 2) + { + debug("caca import error: only version 2 import is supported"); + goto invalid_caca; + } if(size < 4 + control_size + data_size) return 0; - if(control_size < 16 + frames * 32) + if(control_size < 20 + ndirty * 16 + frames * 32) { debug("caca import error: control size %u < expected %u", - (unsigned int)control_size, 16 + frames * 32); + (unsigned int)control_size, 32 + frames * 32); goto invalid_caca; } + /* dirty rectangles info */ + cv->ndirty = ndirty; + for(i = 0; i < ndirty; i++) + { + dirty_xmin = sscanu32(buf + 4 + 20 + 16 * i); + dirty_ymin = sscanu32(buf + 4 + 20 + 16 * i + 4); + dirty_xmax = sscanu32(buf + 4 + 20 + 16 * i + 8); + dirty_ymax = sscanu32(buf + 4 + 20 + 16 * i + 12); + } + for(expected_size = 0, f = 0; f < frames; f++) { unsigned int width, height, duration; uint32_t attr; int x, y, handlex, handley; - width = sscanu32(buf + 4 + 16 + f * 32); - height = sscanu32(buf + 4 + 16 + f * 32 + 4); - duration = sscanu32(buf + 4 + 16 + f * 32 + 8); - attr = sscanu32(buf + 4 + 16 + f * 32 + 12); - x = (int32_t)sscanu32(buf + 4 + 16 + f * 32 + 16); - y = (int32_t)sscanu32(buf + 4 + 16 + f * 32 + 20); - handlex = (int32_t)sscanu32(buf + 4 + 16 + f * 32 + 24); - handley = (int32_t)sscanu32(buf + 4 + 16 + f * 32 + 28); + width = sscanu32(buf + 4 + 20 + 16 * ndirty + f * 32); + height = sscanu32(buf + 4 + 20 + 16 * ndirty + f * 32 + 4); + duration = sscanu32(buf + 4 + + f * 32 + 8); + attr = sscanu32(buf + 4 + 20 + 16 * ndirty + f * 32 + 12); + x = (int32_t)sscanu32(buf + 4 + 20 + 16 * ndirty + f * 32 + 16); + y = (int32_t)sscanu32(buf + 4 + 20 + 16 * ndirty + f * 32 + 20); + handlex = (int32_t)sscanu32(buf + 4 + 20 + 16 * ndirty + f * 32 + 24); + handley = (int32_t)sscanu32(buf + 4 + 20 + 16 * ndirty + f * 32 + 28); expected_size += width * height * 8; if(-handlex < xmin) xmin = -handlex; @@ -296,16 +314,16 @@ static ssize_t import_caca(caca_canvas_t *cv, void const *data, size_t size) { unsigned int width, height; - width = sscanu32(buf + 4 + 16 + f * 32); - height = sscanu32(buf + 4 + 16 + f * 32 + 4); + width = sscanu32(buf + 4 + 20 + ndirty * 16 + f * 32); + height = sscanu32(buf + 4 + 20 + ndirty * 16 + f * 32 + 4); caca_create_frame(cv, f); caca_set_frame(cv, f); - cv->curattr = sscanu32(buf + 4 + 16 + f * 32 + 12); - cv->frames[f].x = (int32_t)sscanu32(buf + 4 + 16 + f * 32 + 16); - cv->frames[f].y = (int32_t)sscanu32(buf + 4 + 16 + f * 32 + 20); - cv->frames[f].handlex = (int32_t)sscanu32(buf + 4 + 16 + f * 32 + 24); - cv->frames[f].handley = (int32_t)sscanu32(buf + 4 + 16 + f * 32 + 28); + cv->curattr = sscanu32(buf + 4 + 20 + ndirty * 16 + f * 32 + 12); + cv->frames[f].x = (int32_t)sscanu32(buf + 4 + 20 + ndirty * 16 + f * 32 + 16); + cv->frames[f].y = (int32_t)sscanu32(buf + 4 + 20 + ndirty * 16 + f * 32 + 20); + cv->frames[f].handlex = (int32_t)sscanu32(buf + 4 + 20 + ndirty * 16 + f * 32 + 24); + cv->frames[f].handley = (int32_t)sscanu32(buf + 4 + 20 + ndirty * 16 + f * 32 + 28); /* FIXME: check for return value */