Kaynağa Gözat

* Replaced all cucul_get_* exporters with a generic cucul_export() function.

* Got rid of static buffers; we now use cucul_free() to free exported
    buffers.
  * Fixed light background in the ANSI exporter by adding escape sequences for
    most terminal emulators.
tags/v0.99.beta14
Sam Hocevar sam 19 yıl önce
ebeveyn
işleme
9e698966f2
8 değiştirilmiş dosya ile 148 ekleme ve 137 silme
  1. +27
    -19
      caca/driver_network.c
  2. +36
    -16
      cucul/cucul.c
  3. +24
    -8
      cucul/cucul.h
  4. +0
    -7
      cucul/cucul_internals.h
  5. +33
    -32
      cucul/export_ansi.c
  6. +14
    -27
      cucul/export_html.c
  7. +7
    -13
      cucul/export_irc.c
  8. +7
    -15
      cucul/export_ps.c

+ 27
- 19
caca/driver_network.c Dosyayı Görüntüle

@@ -85,8 +85,7 @@ struct driver_private

char prefix[sizeof(INIT_PREFIX)];

char *buffer;
int size;
struct cucul_buffer *ex;

int client_count;
struct client *clients;
@@ -169,8 +168,7 @@ static int network_init_graphics(caca_t *kk)
return -1;
}

kk->drv.p->buffer = NULL;
kk->drv.p->size = 0;
kk->drv.p->ex = NULL;

/* Ignore SIGPIPE */
kk->drv.p->sigpipe_handler = signal(SIGPIPE, SIG_IGN);
@@ -191,6 +189,9 @@ static int network_end_graphics(caca_t *kk)
kk->drv.p->clients[i].fd = -1;
}

if(kk->drv.p->ex)
cucul_free(kk->drv.p->ex);

/* Restore SIGPIPE handler */
signal(SIGPIPE, kk->drv.p->sigpipe_handler);

@@ -219,10 +220,17 @@ static void network_display(caca_t *kk)
{
int i;

/* Free the previous export buffer, if any */
if(kk->drv.p->ex)
{
cucul_free(kk->drv.p->ex);
kk->drv.p->ex = NULL;
}

/* Get ANSI representation of the image and skip the end-of buffer
* linefeed ("\r\n\0", 3 bytes) */
kk->drv.p->buffer = cucul_get_ansi(kk->qq, 0, &kk->drv.p->size);
kk->drv.p->size -= 3;
kk->drv.p->ex = cucul_export(kk->qq, CUCUL_FORMAT_ANSI);
kk->drv.p->ex->size -= 3;

for(i = 0; i < kk->drv.p->client_count; i++)
{
@@ -370,7 +378,7 @@ static int send_data(caca_t *kk, struct client *c)
}

/* No error, there's just nothing to send yet */
if(!kk->drv.p->buffer)
if(!kk->drv.p->ex)
return 0;

/* If we have backlog, send the backlog */
@@ -395,7 +403,7 @@ static int send_data(caca_t *kk, struct client *c)
{
c->start += ret;

if(c->stop - c->start + strlen(ANSI_PREFIX) + kk->drv.p->size
if(c->stop - c->start + strlen(ANSI_PREFIX) + kk->drv.p->ex->size
> OUTBUFFER)
{
/* Overflow! Empty buffer and start again */
@@ -406,7 +414,7 @@ static int send_data(caca_t *kk, struct client *c)
}

/* Need to move? */
if(c->stop + strlen(ANSI_PREFIX) + kk->drv.p->size > OUTBUFFER)
if(c->stop + strlen(ANSI_PREFIX) + kk->drv.p->ex->size > OUTBUFFER)
{
memmove(c->outbuf, c->outbuf + c->start, c->stop - c->start);
c->stop -= c->start;
@@ -415,8 +423,8 @@ static int send_data(caca_t *kk, struct client *c)

memcpy(c->outbuf + c->stop, ANSI_PREFIX, strlen(ANSI_PREFIX));
c->stop += strlen(ANSI_PREFIX);
memcpy(c->outbuf + c->stop, kk->drv.p->buffer, kk->drv.p->size);
c->stop += kk->drv.p->size;
memcpy(c->outbuf + c->stop, kk->drv.p->ex->buffer, kk->drv.p->ex->size);
c->stop += kk->drv.p->ex->size;

return 0;
}
@@ -436,7 +444,7 @@ static int send_data(caca_t *kk, struct client *c)

if(ret < (ssize_t)strlen(ANSI_PREFIX))
{
if(strlen(ANSI_PREFIX) + kk->drv.p->size > OUTBUFFER)
if(strlen(ANSI_PREFIX) + kk->drv.p->ex->size > OUTBUFFER)
{
/* Overflow! Empty buffer and start again */
memcpy(c->outbuf, ANSI_RESET, strlen(ANSI_RESET));
@@ -447,14 +455,14 @@ static int send_data(caca_t *kk, struct client *c)

memcpy(c->outbuf, ANSI_PREFIX, strlen(ANSI_PREFIX) - ret);
c->stop = strlen(ANSI_PREFIX) - ret;
memcpy(c->outbuf + c->stop, kk->drv.p->buffer, kk->drv.p->size);
c->stop += kk->drv.p->size;
memcpy(c->outbuf + c->stop, kk->drv.p->ex->buffer, kk->drv.p->ex->size);
c->stop += kk->drv.p->ex->size;

return 0;
}

/* Send actual data */
ret = nonblock_write(c->fd, kk->drv.p->buffer, kk->drv.p->size);
ret = nonblock_write(c->fd, kk->drv.p->ex->buffer, kk->drv.p->ex->size);
if(ret == -1)
{
if(errno == EAGAIN)
@@ -463,9 +471,9 @@ static int send_data(caca_t *kk, struct client *c)
return -1;
}

if(ret < kk->drv.p->size)
if(ret < (int)kk->drv.p->ex->size)
{
if(kk->drv.p->size > OUTBUFFER)
if(kk->drv.p->ex->size > OUTBUFFER)
{
/* Overflow! Empty buffer and start again */
memcpy(c->outbuf, ANSI_RESET, strlen(ANSI_RESET));
@@ -474,8 +482,8 @@ static int send_data(caca_t *kk, struct client *c)
return 0;
}

memcpy(c->outbuf, kk->drv.p->buffer, kk->drv.p->size - ret);
c->stop = kk->drv.p->size - ret;
memcpy(c->outbuf, kk->drv.p->ex->buffer, kk->drv.p->ex->size - ret);
c->stop = kk->drv.p->ex->size - ret;

return 0;
}


+ 36
- 16
cucul/cucul.c Dosyayı Görüntüle

@@ -74,11 +74,6 @@ cucul_t * cucul_init(void)
return NULL;
}

qq->ansi_buffer = NULL;
qq->irc_buffer = NULL;
qq->html3_buffer = NULL;
qq->html_buffer = NULL;

return qq;
}

@@ -277,19 +272,44 @@ void cucul_end(cucul_t *qq)
free(qq->chars);
free(qq->attr);

if(qq->ansi_buffer)
free(qq->ansi_buffer);
if(qq->irc_buffer)
free(qq->irc_buffer);
if(qq->html3_buffer)
free(qq->html3_buffer);
if(qq->html_buffer)
free(qq->html_buffer);
if(qq->ps_buffer)
free(qq->ps_buffer);
free(qq);
}

struct cucul_buffer * cucul_export(cucul_t *qq, enum cucul_format format)
{
struct cucul_buffer *ex;

free(qq);
ex = malloc(sizeof(struct cucul_buffer));

switch(format)
{
case CUCUL_FORMAT_ANSI:
_cucul_get_ansi(qq, ex);
break;
case CUCUL_FORMAT_HTML:
_cucul_get_html(qq, ex);
break;
case CUCUL_FORMAT_HTML3:
_cucul_get_html3(qq, ex);
break;
case CUCUL_FORMAT_IRC:
_cucul_get_irc(qq, ex);
break;
case CUCUL_FORMAT_PS:
_cucul_get_ps(qq, ex);
break;
default:
free(ex);
return NULL;
}

return ex;
}

void cucul_free(struct cucul_buffer *ex)
{
free(ex->buffer);
free(ex);
}

/*


+ 24
- 8
cucul/cucul.h Dosyayı Görüntüle

@@ -28,7 +28,7 @@ extern "C"

/** \brief Colour definitions.
*
* Colours that can be used with caca_set_color().
* Colours that can be used with cucul_set_color().
*/
enum cucul_color
{
@@ -50,6 +50,19 @@ enum cucul_color
CUCUL_COLOR_WHITE = 15 /**< The colour index for white. */
};

/** \brief Export formats
*
* Export formats understood by libcucul.
*/
enum cucul_format
{
CUCUL_FORMAT_ANSI = 0, /**< Export to ANSI format. */
CUCUL_FORMAT_HTML = 1, /**< Export to HTML format. */
CUCUL_FORMAT_HTML3 = 2, /**< Export to old HTMLv3 format. */
CUCUL_FORMAT_IRC = 3, /**< Export to text with mIRC colours. */
CUCUL_FORMAT_PS = 4, /**< Export to PostScript. */
};

/** \brief Internal features.
*
* Internal libcaca features such as the rendering method or the dithering
@@ -200,15 +213,18 @@ void cucul_free_bitmap(cucul_t *, struct cucul_bitmap *);

/** \defgroup exporter Exporters to various formats
*
* These functions exports current image to various text formats
* Returned buffer will be freed() each you'll call the exporter function.
* These functions export the current canvas to various text formats. It
* is necessary to call cucul_free() to dispose of the data.
*
* @{ */
char* cucul_get_html(cucul_t *, int *size);
char* cucul_get_html3(cucul_t *, int *size);
char* cucul_get_irc(cucul_t *, int *size);
char* cucul_get_ansi(cucul_t *, int trailing, int *size);
char* cucul_get_ps(cucul_t *qq, int *size);
struct cucul_buffer
{
unsigned int size;
char *buffer;
};

struct cucul_buffer * cucul_export(cucul_t *, enum cucul_format);
void cucul_free(struct cucul_buffer *);

/* @} */



+ 0
- 7
cucul/cucul_internals.h Dosyayı Görüntüle

@@ -47,13 +47,6 @@ struct cucul_context
enum cucul_feature background, antialiasing, dithering;

unsigned int refcount;

/* Exporters facilities */
char *ansi_buffer;
char *irc_buffer;
char *html3_buffer;
char *html_buffer;
char *ps_buffer;
};

/* Initialisation functions */


+ 33
- 32
cucul/export_ansi.c Dosyayı Görüntüle

@@ -10,7 +10,7 @@
*/

/** \file export.c
* \version \$Id: export.c 361 2006-03-09 13:24:06Z jylam $
* \version \$Id$
* \author Sam Hocevar <sam@zoy.org>
* \author Jean-Yves Lamoureux <jylam@lnxscene.org>
* \brief Export function
@@ -39,28 +39,24 @@
* able to cut/paste the result to a function like printf
* \return buffer containing generated ANSI codes as a big string
*/
char * cucul_get_ansi(cucul_t *qq, int trailing, int *size)
void _cucul_get_ansi(cucul_t *qq, struct cucul_buffer *ex)
{
static int const palette[] =
{
30, 34, 32, 36, 31, 35, 33, 37, /* Both lines (light and dark) are the same, */
30, 34, 32, 36, 31, 35, 33, 37, /* light colors handling is done later */
0, 4, 2, 6, 1, 5, 3, 7,
8, 12, 10, 14, 9, 13, 11, 15
};

char *cur;
unsigned int x, y;

/* 20 bytes assumed for max length per pixel.
/* 23 bytes assumed for max length per pixel ('\e[5;1;3x;4y;9x;10ym' plus
* 4 max bytes for a UTF-8 character).
* Add height*9 to that (zeroes color at the end and jump to next line) */
if(qq->ansi_buffer)
free(qq->ansi_buffer);
qq->ansi_buffer = malloc(((qq->height*9) + (qq->width * qq->height * 20)) * sizeof(char));
if(qq->ansi_buffer == NULL)
return NULL;
ex->size = (qq->height * 9) + (qq->width * qq->height * 23);
ex->buffer = malloc(ex->size);

cur = qq->ansi_buffer;

// *cur++ = '';
cur = ex->buffer;

for(y = 0; y < qq->height; y++)
{
@@ -73,34 +69,39 @@ char * cucul_get_ansi(cucul_t *qq, int trailing, int *size)
for(x = 0; x < qq->width; x++)
{
uint8_t fg = palette[lineattr[x] & 0x0f];
uint8_t bg = (palette[lineattr[x] >> 4])+10;
uint8_t bg = palette[lineattr[x] >> 4];
uint32_t c = linechar[x];

if(!trailing)
cur += sprintf(cur, "\033[");
else
cur += sprintf(cur, "\\033[");
if(fg != prevfg || bg != prevbg)
{
cur += sprintf(cur, "\033[0;");

if(fg < 8)
if(bg < 8)
cur += sprintf(cur, "3%d;4%dm", fg, bg);
else
cur += sprintf(cur, "5;3%d;4%d;10%dm",
fg, bg - 8, bg - 8);
else
if(bg < 8)
cur += sprintf(cur, "1;3%d;4%d;9%dm",
fg - 8, bg, fg - 8);
else
cur += sprintf(cur, "5;1;3%d;4%d;9%d;10%dm",
fg - 8, bg - 8, fg - 8, bg - 8);
}

if(fg > 7)
cur += sprintf(cur, "1;%d;%dm",fg,bg);
else
cur += sprintf(cur, "0;%d;%dm",fg,bg);
*cur++ = c & 0x7f;
if((c == '%') && trailing)
*cur++ = c & 0x7f;

prevfg = fg;
prevbg = bg;
}
if(!trailing)
cur += sprintf(cur, "\033[0m\r\n");
else
cur += sprintf(cur, "\\033[0m\\n\n");

cur += sprintf(cur, "\033[0m\r\n");
}

/* Crop to really used size */
*size = (strlen(qq->ansi_buffer) + 1)* sizeof(char);
qq->ansi_buffer = realloc(qq->ansi_buffer, *size);

return qq->ansi_buffer;
ex->size = strlen(ex->buffer) + 1;
ex->buffer = realloc(ex->buffer, ex->size);
}


+ 14
- 27
cucul/export_html.c Dosyayı Görüntüle

@@ -10,7 +10,7 @@
*/

/** \file export.c
* \version \$Id: export.c 361 2006-03-09 13:24:06Z jylam $
* \version \$Id$
* \author Sam Hocevar <sam@zoy.org>
* \author Jean-Yves Lamoureux <jylam@lnxscene.org>
* \brief Export function
@@ -38,7 +38,7 @@
* This function generates and returns the HTML representation of
* the current image.
*/
char* cucul_get_html(cucul_t *qq, int *size)
void _cucul_get_html(cucul_t *qq, struct cucul_buffer *ex)
{
static int const palette[] =
{
@@ -51,15 +51,10 @@ char* cucul_get_html(cucul_t *qq, int *size)
/* 13000 -> css palette
* 40 -> max size used for a pixel (plus 10, never know)*/
/* FIXME: Check this value */
if(qq->html_buffer)
free(qq->html_buffer);
ex->size = 13000 + (qq->width * qq->height * 40);
ex->buffer = malloc(ex->size);

qq->html_buffer = malloc((13000 + ((qq->width*qq->height) * 40)) * sizeof(char));
if(qq->html_buffer == NULL)
return NULL;


cur = qq->html_buffer;
cur = ex->buffer;

/* HTML header */
cur += sprintf(cur, "<html>\n<head>\n<title>Generated by libcaca %s</title>\n", VERSION);
@@ -104,10 +99,8 @@ char* cucul_get_html(cucul_t *qq, int *size)
cur += sprintf(cur, "</div></body></html>\n");

/* Crop to really used size */
*size = (strlen(qq->html_buffer) + 1) * sizeof(char);
qq->html_buffer = realloc(qq->html_buffer, *size);

return qq->html_buffer;
ex->size = strlen(ex->buffer) + 1;
ex->buffer = realloc(ex->buffer, ex->size);
}


@@ -119,7 +112,7 @@ char* cucul_get_html(cucul_t *qq, int *size)
* Won't work under gecko (mozilla rendering engine) unless you set
* a correct header.
*/
char* cucul_get_html3(cucul_t *qq, int *size)
void _cucul_get_html3(cucul_t *qq, struct cucul_buffer *ex)
{
static int const palette[] =
{
@@ -128,20 +121,16 @@ char* cucul_get_html3(cucul_t *qq, int *size)
0x444444, 0x4444ff, 0x44ff44, 0x44ffff,
0xff4444, 0xff44ff, 0xffff44, 0xffffff,
};

char *cur;
unsigned int x, y, len;

/* 13000 -> css palette
* 40 -> max size used for a pixel (plus 10, never know) */
ex->size = 13000 + (qq->width * qq->height * 40);
ex->buffer = malloc(ex->size);

if(qq->html3_buffer)
free(qq->html3_buffer);

qq->html3_buffer = malloc((13000 + ((qq->width*qq->height)*40))*sizeof(char));
if(qq->html3_buffer == NULL)
return NULL;

cur = qq->html3_buffer;
cur = ex->buffer;

/* Table */
cur += sprintf(cur, "<table cols='%d' cellpadding='0' cellspacing='0'>\n",
@@ -189,10 +178,8 @@ char* cucul_get_html3(cucul_t *qq, int *size)
cur += sprintf(cur, "</table>\n");

/* Crop to really used size */
*size = (strlen(qq->html3_buffer) + 1) * sizeof(char);
qq->html3_buffer = realloc(qq->html3_buffer, *size);
return qq->html3_buffer;
ex->size = strlen(ex->buffer) + 1;
ex->buffer = realloc(ex->buffer, ex->size);
}



+ 7
- 13
cucul/export_irc.c Dosyayı Görüntüle

@@ -10,7 +10,7 @@
*/

/** \file export.c
* \version \$Id: export.c 361 2006-03-09 13:24:06Z jylam $
* \version \$Id$
* \author Sam Hocevar <sam@zoy.org>
* \author Jean-Yves Lamoureux <jylam@lnxscene.org>
* \brief Export function
@@ -36,7 +36,7 @@
* This function generates and returns an IRC representation of
* the current image.
*/
char* cucul_get_irc(cucul_t *qq, int *size)
void _cucul_get_irc(cucul_t *qq, struct cucul_buffer *ex)
{
static int const palette[] =
{
@@ -55,14 +55,10 @@ char* cucul_get_irc(cucul_t *qq, int *size)
* In real life, the average bytes per pixel value will be around 5.
*/

if(qq->irc_buffer)
free(qq->irc_buffer);
ex->size = 2 + (qq->width * qq->height * 11);
ex->buffer = malloc(ex->size);

qq->irc_buffer = malloc((2 + (qq->width * qq->height * 11)) * sizeof(char));
if(qq->irc_buffer == NULL)
return NULL;

cur = qq->irc_buffer;
cur = ex->buffer;

*cur++ = '\x0f';

@@ -114,8 +110,6 @@ char* cucul_get_irc(cucul_t *qq, int *size)
*cur++ = '\x0f';

/* Crop to really used size */
*size = (strlen(qq->irc_buffer) + 1) * sizeof(char);
qq->irc_buffer = realloc(qq->irc_buffer, *size);
return qq->irc_buffer;
ex->size = strlen(ex->buffer) + 1;
ex->buffer = realloc(ex->buffer, ex->size);
}

+ 7
- 15
cucul/export_ps.c Dosyayı Görüntüle

@@ -59,7 +59,7 @@ static char const *ps_header =
* This function generates and returns a Postscript representation of
* the current image.
*/
char* cucul_get_ps(cucul_t *qq, int *size)
void _cucul_get_ps(cucul_t *qq, struct cucul_buffer *ex)
{
char *cur;
int x, y;
@@ -87,17 +87,15 @@ char* cucul_get_ps(cucul_t *qq, int *size)
};


if(qq->ps_buffer)
free(qq->ps_buffer);

/* 200 is arbitrary but should be ok */
qq->ps_buffer = malloc((strlen(ps_header) + (qq->height*qq->width)*200) * sizeof(char));
cur = qq->ps_buffer;
ex->size = strlen(ps_header) + (qq->width * qq->height * 200);
ex->buffer = malloc(ex->size);

cur = ex->buffer;

/* Header */
cur += sprintf(cur, "%s", ps_header);


/* Background, drawn using csquare macro defined in header */
for(y=(int)(qq->height-1);y>=0; y--) {
uint8_t *lineattr = qq->attr + y * qq->width;
@@ -139,13 +137,7 @@ char* cucul_get_ps(cucul_t *qq, int *size)
cur += sprintf(cur, "showpage");

/* Crop to really used size */
*size = (strlen(qq->ps_buffer) + 1) * sizeof(char);

qq->ps_buffer = realloc(qq->ps_buffer, *size);

return qq->ps_buffer;

ex->size = strlen(ex->buffer) + 1;
ex->buffer = realloc(ex->buffer, ex->size);
}




Yükleniyor…
İptal
Kaydet