Browse Source

* Added a new "caca" exporter.

* Removed most code from the raw driver and replaced it with a call to the
    caca exporter.
  * Slightly changed the caca export format and updated code accordingly.
  * Improved cacaserver error reporting.
tags/v0.99.beta14
Sam Hocevar sam 18 years ago
parent
commit
ea3bde92a4
4 changed files with 91 additions and 52 deletions
  1. +5
    -22
      caca/driver_raw.c
  2. +16
    -17
      cucul/cucul.c
  3. +46
    -1
      cucul/export.c
  4. +24
    -12
      src/cacaserver.c

+ 5
- 22
caca/driver_raw.c View File

@@ -53,30 +53,13 @@ static unsigned int raw_get_window_height(caca_display_t *dp)

static void raw_display(caca_display_t *dp)
{
uint32_t *attr = dp->cv->attr;
uint32_t *chars = dp->cv->chars;
uint32_t w, h;
unsigned int n;
cucul_buffer_t *buffer;

w = dp->cv->width;
h = dp->cv->height;

fprintf(stdout, "CACA%c%c%c%c%c%c%c%c",
(w >> 24), (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff,
(h >> 24), (h >> 16) & 0xff, (h >> 8) & 0xff, h & 0xff);

for(n = dp->cv->height * dp->cv->width; n--; )
{
uint32_t ch = *chars++;
uint32_t a = *attr++;

fprintf(stdout, "%c%c%c%c%c%c%c%c",
(ch >> 24), (ch >> 16) & 0xff, (ch >> 8) & 0xff, ch & 0xff,
(a >> 24), (a >> 16) & 0xff, (a >> 8) & 0xff, a & 0xff);
}

fprintf(stdout, "ACAC");
buffer = cucul_create_export(dp->cv, "caca");
fwrite(cucul_get_buffer_data(buffer),
cucul_get_buffer_size(buffer), 1, stdout);
fflush(stdout);
cucul_free_buffer(buffer);
}

static void raw_handle_resize(caca_display_t *dp)


+ 16
- 17
cucul/cucul.c View File

@@ -87,25 +87,24 @@ cucul_canvas_t *cucul_load_canvas(void *data, unsigned int size)
uint8_t *buf = (uint8_t *)data;
unsigned int width, height, n;

if(size < 12)
if(size < 16)
return NULL;

if(buf[0] != 'C' || buf[1] != 'A' || buf[2] != 'C' || buf[3] != 'A')
return NULL;

width = ((uint32_t)buf[4] << 24) | ((uint32_t)buf[5] << 16)
| ((uint32_t)buf[6] << 8) | (uint32_t)buf[7];
height = ((uint32_t)buf[8] << 24) | ((uint32_t)buf[9] << 16)
if(buf[4] != 'C' || buf[5] != 'A' || buf[6] != 'N' || buf[7] != 'V')
return NULL;

width = ((uint32_t)buf[8] << 24) | ((uint32_t)buf[9] << 16)
| ((uint32_t)buf[10] << 8) | (uint32_t)buf[11];
height = ((uint32_t)buf[12] << 24) | ((uint32_t)buf[13] << 16)
| ((uint32_t)buf[14] << 8) | (uint32_t)buf[15];

if(!width || !height)
return NULL;

if(size != 12 + width * height * 8 + 4)
return NULL;

if(buf[size - 4] != 'A' || buf[size - 3] != 'C'
|| buf[size - 2] != 'A' || buf[size - 1] != 'C')
if(size != 16 + width * height * 8)
return NULL;

cv = cucul_create_canvas(width, height);
@@ -115,14 +114,14 @@ cucul_canvas_t *cucul_load_canvas(void *data, unsigned int size)

for(n = height * width; n--; )
{
cv->chars[n] = ((uint32_t)buf[12 + 8 * n] << 24)
| ((uint32_t)buf[13 + 8 * n] << 16)
| ((uint32_t)buf[14 + 8 * n] << 8)
| (uint32_t)buf[15 + 8 * n];
cv->attr[n] = ((uint32_t)buf[16 + 8 * n] << 24)
| ((uint32_t)buf[17 + 8 * n] << 16)
| ((uint32_t)buf[18 + 8 * n] << 8)
| (uint32_t)buf[19 + 8 * n];
cv->chars[n] = ((uint32_t)buf[16 + 0 + 8 * n] << 24)
| ((uint32_t)buf[16 + 1 + 8 * n] << 16)
| ((uint32_t)buf[16 + 2 + 8 * n] << 8)
| (uint32_t)buf[16 + 3 + 8 * n];
cv->attr[n] = ((uint32_t)buf[16 + 4 + 8 * n] << 24)
| ((uint32_t)buf[16 + 5 + 8 * n] << 16)
| ((uint32_t)buf[16 + 6 + 8 * n] << 8)
| (uint32_t)buf[16 + 7 + 8 * n];
}

return cv;


+ 46
- 1
cucul/export.c View File

@@ -27,6 +27,7 @@
#include "cucul.h"
#include "cucul_internals.h"

static void export_caca(cucul_canvas_t *, cucul_buffer_t *);
static void export_ansi(cucul_canvas_t *, cucul_buffer_t *);
static void export_html(cucul_canvas_t *, cucul_buffer_t *);
static void export_html3(cucul_canvas_t *, cucul_buffer_t *);
@@ -44,6 +45,8 @@ static void export_tga(cucul_canvas_t *, cucul_buffer_t *);
*
* Valid values for \e format are:
*
* \li \e "caca": export native libcaca files.
*
* \li \e "ansi": export ANSI art (CP437 charset with ANSI colour codes).
*
* \li \e "html": export an HTML page with CSS information.
@@ -70,7 +73,9 @@ cucul_buffer_t * cucul_create_export(cucul_canvas_t *cv, char const *format)
ex->size = 0;
ex->data = NULL;

if(!strcasecmp("ansi", format))
if(!strcasecmp("caca", format))
export_caca(cv, ex);
else if(!strcasecmp("ansi", format))
export_ansi(cv, ex);
else if(!strcasecmp("html", format))
export_html(cv, ex);
@@ -107,6 +112,7 @@ char const * const * cucul_get_export_list(void)
{
static char const * const list[] =
{
"caca", "native libcaca format",
"ansi", "ANSI",
"html", "HTML",
"html3", "backwards-compatible HTML",
@@ -124,6 +130,45 @@ char const * const * cucul_get_export_list(void)
* XXX: the following functions are local.
*/

/* Generate a native libcaca canvas file. */
static void export_caca(cucul_canvas_t *cv, cucul_buffer_t *ex)
{
uint32_t *attr = cv->attr;
uint32_t *chars = cv->chars;
char *cur;
uint32_t w, h;
unsigned int n;

/* 16 bytes for the canvas, 8 bytes for each character cell. */
ex->size = 16 + 8 * cv->width * cv->height;
ex->data = malloc(ex->size);

cur = ex->data;

w = cv->width;
h = cv->height;

cur += sprintf(cur, "CACACANV%c%c%c%c%c%c%c%c",
(w >> 24), (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff,
(h >> 24), (h >> 16) & 0xff, (h >> 8) & 0xff, h & 0xff);

for(n = cv->height * cv->width; n--; )
{
uint32_t ch = *chars++;
uint32_t a = *attr++;

*cur++ = ch >> 24;
*cur++ = (ch >> 16) & 0xff;
*cur++ = (ch >> 8) & 0xff;
*cur++ = ch & 0xff;

*cur++ = a >> 24;
*cur++ = (a >> 16) & 0xff;
*cur++ = (a >> 8) & 0xff;
*cur++ = a & 0xff;
}
}

/* Generate ANSI representation of current canvas. */
static void export_ansi(cucul_canvas_t *cv, cucul_buffer_t *ex)
{


+ 24
- 12
src/cacaserver.c View File

@@ -134,7 +134,7 @@ int main(void)
#endif
server = malloc(sizeof(struct server));

server->input = malloc(12);
server->input = malloc(16);
server->read = 0;

server->client_count = 0;
@@ -205,22 +205,22 @@ int main(void)
manage_connections(server);

/* Read data from stdin */
read(0, buf, 12);
read(0, buf, 16);

while(buf[0] != 'C' && buf[1] != 'A' && buf[2] != 'C' && buf[3] != 'A')
while(buf[0] != 'C' || buf[1] != 'A' || buf[2] != 'C' || buf[3] != 'A')
{
memmove(buf, buf + 1, 11);
read(0, buf + 11, 1);
memmove(buf, buf + 1, 15);
read(0, buf + 15, 1);
}

width = ((uint32_t)buf[4] << 24) | ((uint32_t)buf[5] << 16)
| ((uint32_t)buf[6] << 8) | (uint32_t)buf[7];
height = ((uint32_t)buf[8] << 24) | ((uint32_t)buf[9] << 16)
width = ((uint32_t)buf[8] << 24) | ((uint32_t)buf[9] << 16)
| ((uint32_t)buf[10] << 8) | (uint32_t)buf[11];
height = ((uint32_t)buf[12] << 24) | ((uint32_t)buf[13] << 16)
| ((uint32_t)buf[14] << 8) | (uint32_t)buf[15];

size = 12 + width * height * 8 + 4;
size = 16 + width * height * 8;
buf = server->input = realloc(server->input, size);
read(0, buf + 12, size - 12);
read(0, buf + 16, size - 16);

/* Free the previous canvas, if any */
if(server->canvas)
@@ -239,9 +239,11 @@ int main(void)
}

/* Get ANSI representation of the image and skip the end-of buffer
* linefeed ("\r\n\0", 3 bytes) */
* linefeed ("\r\n", 2 bytes) */
server->buffer = cucul_create_export(server->canvas, "ansi");
server->buflen -= 3;
server->bufdata = cucul_get_buffer_data(server->buffer);
server->buflen = cucul_get_buffer_size(server->buffer);
server->buflen -= 2;

for(i = 0; i < server->client_count; i++)
{
@@ -410,7 +412,11 @@ static int send_data(struct server *server, struct client *c)
if(errno == EAGAIN)
ret = 0;
else
{
fprintf(stderr, "client %i failed (%s)\n",
c->fd, strerror(errno));
return -1;
}
}

if(ret == c->stop - c->start)
@@ -458,7 +464,10 @@ static int send_data(struct server *server, struct client *c)
if(errno == EAGAIN)
ret = 0;
else
{
fprintf(stderr, "client %i failed (%s)\n", c->fd, strerror(errno));
return -1;
}
}

if(ret < (ssize_t)strlen(ANSI_PREFIX))
@@ -487,7 +496,10 @@ static int send_data(struct server *server, struct client *c)
if(errno == EAGAIN)
ret = 0;
else
{
fprintf(stderr, "client %i failed (%s)\n", c->fd, strerror(errno));
return -1;
}
}

if(ret < (int)server->buflen)


Loading…
Cancel
Save