@@ -14,7 +14,7 @@ libcucul_la_SOURCES = \ | |||
cucul.c \ | |||
cucul.h \ | |||
cucul_internals.h \ | |||
buffer.c \ | |||
legacy.c \ | |||
canvas.c \ | |||
transform.c \ | |||
charset.c \ | |||
@@ -136,12 +136,6 @@ int cucul_set_color_ansi(cucul_canvas_t *cv, unsigned char fg, unsigned char bg) | |||
return 0; | |||
} | |||
/* Legacy function for old programs */ | |||
int cucul_set_color(cucul_canvas_t *cv, unsigned char fg, unsigned char bg) | |||
{ | |||
return cucul_set_color_ansi(cv, fg, bg); | |||
} | |||
/** \brief Set the default colour pair for text (truecolor version). | |||
* | |||
* Set the default ARGB colour pair for text drawing. String functions such | |||
@@ -187,12 +181,6 @@ int cucul_set_color_argb(cucul_canvas_t *cv, unsigned int fg, unsigned int bg) | |||
return 0; | |||
} | |||
/* Legacy function for old programs */ | |||
int cucul_set_truecolor(cucul_canvas_t *cv, unsigned int fg, unsigned int bg) | |||
{ | |||
return cucul_set_color_argb(cv, fg, bg); | |||
} | |||
/* | |||
* XXX: the following functions are local | |||
*/ | |||
@@ -35,8 +35,6 @@ extern "C" | |||
typedef struct cucul_canvas cucul_canvas_t; | |||
/** dither structure */ | |||
typedef struct cucul_dither cucul_dither_t; | |||
/** data buffer structure */ | |||
typedef struct cucul_buffer cucul_buffer_t; | |||
/** font structure */ | |||
typedef struct cucul_font cucul_font_t; | |||
@@ -84,18 +82,6 @@ int cucul_free_canvas(cucul_canvas_t *); | |||
int cucul_rand(int, int); | |||
/* @} */ | |||
/** \defgroup buffer libcucul buffer handling | |||
* | |||
* These functions provide methods to handle libcucul buffers. | |||
* | |||
* @{ */ | |||
cucul_buffer_t *cucul_load_memory(void *, unsigned long int); | |||
cucul_buffer_t *cucul_load_file(char const *); | |||
unsigned long int cucul_get_buffer_size(cucul_buffer_t *); | |||
void * cucul_get_buffer_data(cucul_buffer_t *); | |||
int cucul_free_buffer(cucul_buffer_t *); | |||
/* @} */ | |||
/** \defgroup canvas libcucul canvas drawing | |||
* | |||
* These functions provide low-level character printing routines and | |||
@@ -230,23 +216,35 @@ int cucul_free_font(cucul_font_t *); | |||
* the current canvas to various text formats. | |||
* | |||
* @{ */ | |||
cucul_buffer_t * cucul_export_canvas(cucul_canvas_t *, char const *); | |||
void *cucul_export(cucul_canvas_t *, char const *, unsigned long int *); | |||
long int cucul_import(cucul_canvas_t *, unsigned char const *, | |||
unsigned long int, char const *); | |||
char const * const * cucul_get_export_list(void); | |||
cucul_canvas_t * cucul_import_canvas(cucul_buffer_t *, char const *); | |||
char const * const * cucul_get_import_list(void); | |||
/* @} */ | |||
#if !defined(_DOXYGEN_SKIP_ME) | |||
/* Legacy stuff from beta versions, will probably disappear in 1.0 */ | |||
/* Legacy stuff from beta versions, will probably disappear in 1.0 */ | |||
typedef struct cucul_buffer cucul_buffer_t; | |||
# ifdef __GNUC__ | |||
# define CUCUL_DEPRECATED __attribute__ ((deprecated)) | |||
# else | |||
# define CUCUL_DEPRECATED | |||
# endif | |||
int cucul_set_color(cucul_canvas_t *, unsigned char, | |||
unsigned char) CUCUL_DEPRECATED; | |||
int cucul_set_truecolor(cucul_canvas_t *, unsigned int, | |||
unsigned int) CUCUL_DEPRECATED; | |||
int cucul_set_color(cucul_canvas_t *, unsigned char, | |||
unsigned char) CUCUL_DEPRECATED; | |||
int cucul_set_truecolor(cucul_canvas_t *, unsigned int, | |||
unsigned int) CUCUL_DEPRECATED; | |||
cucul_buffer_t *cucul_load_memory(void *, | |||
unsigned long int) CUCUL_DEPRECATED; | |||
cucul_buffer_t *cucul_load_file(char const *) CUCUL_DEPRECATED; | |||
unsigned long int cucul_get_buffer_size(cucul_buffer_t *) CUCUL_DEPRECATED; | |||
void * cucul_get_buffer_data(cucul_buffer_t *) CUCUL_DEPRECATED; | |||
int cucul_free_buffer(cucul_buffer_t *) CUCUL_DEPRECATED; | |||
cucul_buffer_t * cucul_export_canvas(cucul_canvas_t *, | |||
char const *) CUCUL_DEPRECATED; | |||
cucul_canvas_t * cucul_import_canvas(cucul_buffer_t *, | |||
char const *) CUCUL_DEPRECATED; | |||
# define CUCUL_COLOR_BLACK CUCUL_BLACK | |||
# define CUCUL_COLOR_BLUE CUCUL_BLUE | |||
# define CUCUL_COLOR_GREEN CUCUL_GREEN | |||
@@ -47,22 +47,21 @@ static inline int sprintu16(char *s, uint16_t x) | |||
return 2; | |||
} | |||
static int export_caca(cucul_canvas_t *, cucul_buffer_t *); | |||
static int export_ansi(cucul_canvas_t *, cucul_buffer_t *); | |||
static int export_utf8(cucul_canvas_t *, cucul_buffer_t *, int); | |||
static int export_html(cucul_canvas_t *, cucul_buffer_t *); | |||
static int export_html3(cucul_canvas_t *, cucul_buffer_t *); | |||
static int export_irc(cucul_canvas_t *, cucul_buffer_t *); | |||
static int export_ps(cucul_canvas_t *, cucul_buffer_t *); | |||
static int export_svg(cucul_canvas_t *, cucul_buffer_t *); | |||
static int export_tga(cucul_canvas_t *, cucul_buffer_t *); | |||
static void *export_caca(cucul_canvas_t *, unsigned long int *); | |||
static void *export_ansi(cucul_canvas_t *, unsigned long int *); | |||
static void *export_utf8(cucul_canvas_t *, unsigned long int *, int); | |||
static void *export_html(cucul_canvas_t *, unsigned long int *); | |||
static void *export_html3(cucul_canvas_t *, unsigned long int *); | |||
static void *export_irc(cucul_canvas_t *, unsigned long int *); | |||
static void *export_ps(cucul_canvas_t *, unsigned long int *); | |||
static void *export_svg(cucul_canvas_t *, unsigned long int *); | |||
static void *export_tga(cucul_canvas_t *, unsigned long int *); | |||
/** \brief Export a canvas into a foreign format. | |||
* | |||
* This function exports a libcucul canvas into various foreign formats such | |||
* as ANSI art, HTML, IRC colours, etc. One should use cucul_get_buffer_data() | |||
* and cucul_get_buffer_size() to access the buffer contents. The allocated | |||
* data is valid until cucul_free_buffer() is called. | |||
* as ANSI art, HTML, IRC colours, etc. The returned pointer should be passed | |||
* to free() to release the allocated storage when it is no longer needed. | |||
* | |||
* Valid values for \c format are: | |||
* - \c "caca": export native libcaca files. | |||
@@ -81,57 +80,47 @@ static int export_tga(cucul_canvas_t *, cucul_buffer_t *); | |||
* | |||
* \param cv A libcucul canvas | |||
* \param format A string describing the requested output format. | |||
* \return A libcucul buffer, or NULL in case of error. | |||
* \param bytes A pointer to an unsigned long integer where the number of | |||
* allocated bytes will be written. | |||
* \return A pointer to the exported memory area, or NULL in case of error. | |||
*/ | |||
cucul_buffer_t * cucul_export_canvas(cucul_canvas_t *cv, char const *format) | |||
void *cucul_export(cucul_canvas_t *cv, char const *format, | |||
unsigned long int *bytes) | |||
{ | |||
cucul_buffer_t *ex; | |||
int ret = -1; | |||
if(!strcasecmp("caca", format)) | |||
return export_caca(cv, bytes); | |||
ex = malloc(sizeof(cucul_buffer_t)); | |||
if(!ex) | |||
{ | |||
#if defined(HAVE_ERRNO_H) | |||
errno = ENOMEM; | |||
#endif | |||
return NULL; | |||
} | |||
if(!strcasecmp("ansi", format)) | |||
return export_ansi(cv, bytes); | |||
ex->size = 0; | |||
ex->data = NULL; | |||
ex->user_data = 0; | |||
if(!strcasecmp("utf8", format)) | |||
return export_utf8(cv, bytes, 0); | |||
if(!strcasecmp("utf8cr", format)) | |||
return export_utf8(cv, bytes, 1); | |||
if(!strcasecmp("html", format)) | |||
return export_html(cv, bytes); | |||
if(!strcasecmp("html3", format)) | |||
return export_html3(cv, bytes); | |||
if(!strcasecmp("irc", format)) | |||
return export_irc(cv, bytes); | |||
if(!strcasecmp("ps", format)) | |||
return export_ps(cv, bytes); | |||
if(!strcasecmp("svg", format)) | |||
return export_svg(cv, bytes); | |||
if(!strcasecmp("tga", format)) | |||
return export_tga(cv, bytes); | |||
if(!strcasecmp("caca", format)) | |||
ret = export_caca(cv, ex); | |||
else if(!strcasecmp("ansi", format)) | |||
ret = export_ansi(cv, ex); | |||
else if(!strcasecmp("utf8", format)) | |||
ret = export_utf8(cv, ex, 0); | |||
else if(!strcasecmp("utf8cr", format)) | |||
ret = export_utf8(cv, ex, 1); | |||
else if(!strcasecmp("html", format)) | |||
ret = export_html(cv, ex); | |||
else if(!strcasecmp("html3", format)) | |||
ret = export_html3(cv, ex); | |||
else if(!strcasecmp("irc", format)) | |||
ret = export_irc(cv, ex); | |||
else if(!strcasecmp("ps", format)) | |||
ret = export_ps(cv, ex); | |||
else if(!strcasecmp("svg", format)) | |||
ret = export_svg(cv, ex); | |||
else if(!strcasecmp("tga", format)) | |||
ret = export_tga(cv, ex); | |||
if(ret < 0) | |||
{ | |||
free(ex); | |||
#if defined(HAVE_ERRNO_H) | |||
errno = EINVAL; | |||
errno = EINVAL; | |||
#endif | |||
return NULL; | |||
} | |||
return ex; | |||
return NULL; | |||
} | |||
/** \brief Get available export formats | |||
@@ -170,11 +159,11 @@ char const * const * cucul_get_export_list(void) | |||
*/ | |||
/* Generate a native libcaca canvas file. */ | |||
static int export_caca(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
static void *export_caca(cucul_canvas_t *cv, unsigned long int *bytes) | |||
{ | |||
uint32_t *attrs = cv->attrs; | |||
uint32_t *chars = cv->chars; | |||
char *cur; | |||
char *data, *cur; | |||
unsigned int n; | |||
/* 44 bytes for the header: | |||
@@ -182,10 +171,8 @@ static int export_caca(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
* - 16 bytes for the canvas header | |||
* - 24 bytes for the frame info | |||
* 8 bytes for each character cell */ | |||
ex->size = 44 + 8 * cv->width * cv->height; | |||
ex->data = malloc(ex->size); | |||
cur = ex->data; | |||
*bytes = 44 + 8 * cv->width * cv->height; | |||
cur = data = malloc(*bytes); | |||
/* magic */ | |||
cur += sprintf(cur, "%s", "\xCA\xCA" "CV"); | |||
@@ -212,7 +199,7 @@ static int export_caca(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
cur += sprintu32(cur, *attrs++); | |||
} | |||
return 0; | |||
return data; | |||
} | |||
/* | |||
@@ -272,7 +259,7 @@ static int export_caca(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
*/ | |||
/* Generate UTF-8 representation of current canvas. */ | |||
static int export_utf8(cucul_canvas_t *cv, cucul_buffer_t *ex, int cr) | |||
static void *export_utf8(cucul_canvas_t *cv, unsigned long int *bytes, int cr) | |||
{ | |||
static uint8_t const palette[] = | |||
{ | |||
@@ -280,16 +267,14 @@ static int export_utf8(cucul_canvas_t *cv, cucul_buffer_t *ex, int cr) | |||
8, 12, 10, 14, 9, 13, 11, 15 | |||
}; | |||
char *cur; | |||
char *data, *cur; | |||
unsigned int x, y; | |||
/* 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) */ | |||
ex->size = (cv->height * 9) + (cv->width * cv->height * 23); | |||
ex->data = malloc(ex->size); | |||
cur = ex->data; | |||
*bytes = (cv->height * 9) + (cv->width * cv->height * 23); | |||
cur = data = malloc(*bytes); | |||
for(y = 0; y < cv->height; y++) | |||
{ | |||
@@ -344,14 +329,14 @@ static int export_utf8(cucul_canvas_t *cv, cucul_buffer_t *ex, int cr) | |||
} | |||
/* Crop to really used size */ | |||
ex->size = (uintptr_t)(cur - ex->data); | |||
ex->data = realloc(ex->data, ex->size); | |||
*bytes = (uintptr_t)(cur - data); | |||
data = realloc(data, *bytes); | |||
return 0; | |||
return data; | |||
} | |||
/* Generate ANSI representation of current canvas. */ | |||
static int export_ansi(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
static void *export_ansi(cucul_canvas_t *cv, unsigned long int *bytes) | |||
{ | |||
static uint8_t const palette[] = | |||
{ | |||
@@ -359,7 +344,7 @@ static int export_ansi(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
8, 12, 10, 14, 9, 13, 11, 15 | |||
}; | |||
char *cur; | |||
char *data, *cur; | |||
unsigned int x, y; | |||
uint8_t prevfg = -1; | |||
@@ -368,10 +353,8 @@ static int export_ansi(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
/* 16 bytes assumed for max length per pixel ('\e[5;1;3x;4ym' plus | |||
* 1 byte for a CP437 character). | |||
* Add height*9 to that (zeroes color at the end and jump to next line) */ | |||
ex->size = (cv->height * 9) + (cv->width * cv->height * 16); | |||
ex->data = malloc(ex->size); | |||
cur = ex->data; | |||
*bytes = (cv->height * 9) + (cv->width * cv->height * 16); | |||
cur = data = malloc(*bytes); | |||
for(y = 0; y < cv->height; y++) | |||
{ | |||
@@ -422,16 +405,16 @@ static int export_ansi(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
} | |||
/* Crop to really used size */ | |||
ex->size = (uintptr_t)(cur - ex->data); | |||
ex->data = realloc(ex->data, ex->size); | |||
*bytes = (uintptr_t)(cur - data); | |||
data = realloc(data, *bytes); | |||
return 0; | |||
return data; | |||
} | |||
/* Generate HTML representation of current canvas. */ | |||
static int export_html(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
static void *export_html(cucul_canvas_t *cv, unsigned long int *bytes) | |||
{ | |||
char *cur; | |||
char *data, *cur; | |||
unsigned int x, y, len; | |||
/* The HTML header: less than 1000 bytes | |||
@@ -440,10 +423,8 @@ static int export_html(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
* 83 chars for ";font-weight..." | |||
* up to 9 chars for "&#xxxxxx;", far less for pure ASCII | |||
* 7 chars for "</span>" */ | |||
ex->size = 1000 + cv->height * (7 + cv->width * (47 + 83 + 9 + 7)); | |||
ex->data = malloc(ex->size); | |||
cur = ex->data; | |||
*bytes = 1000 + cv->height * (7 + cv->width * (47 + 83 + 9 + 7)); | |||
cur = data = malloc(*bytes); | |||
/* HTML header */ | |||
cur += sprintf(cur, "<html><head>\n"); | |||
@@ -498,19 +479,19 @@ static int export_html(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
cur += sprintf(cur, "</div></body></html>\n"); | |||
/* Crop to really used size */ | |||
ex->size = strlen(ex->data) + 1; | |||
ex->data = realloc(ex->data, ex->size); | |||
*bytes = (uintptr_t)(cur - data); | |||
data = realloc(data, *bytes); | |||
return 0; | |||
return data; | |||
} | |||
/* Export an HTML3 document. This function is way bigger than export_html(), | |||
* but permits viewing in old browsers (or limited ones such as links). It | |||
* will not work under gecko (mozilla rendering engine) unless you set a | |||
* correct header. */ | |||
static int export_html3(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
static void *export_html3(cucul_canvas_t *cv, unsigned long int *bytes) | |||
{ | |||
char *cur; | |||
char *data, *cur; | |||
unsigned int x, y, len; | |||
/* The HTML table markup: less than 1000 bytes | |||
@@ -519,10 +500,8 @@ static int export_html3(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
* up to 36 chars for "<b><i><u><blink></blink></u></i></b>" | |||
* up to 9 chars for "&#xxxxxx;", far less for pure ASCII | |||
* 12 chars for "</font></td>" */ | |||
ex->size = 1000 + cv->height * (10 + cv->width * (40 + 36 + 9 + 12)); | |||
ex->data = malloc(ex->size); | |||
cur = ex->data; | |||
*bytes = 1000 + cv->height * (10 + cv->width * (40 + 36 + 9 + 12)); | |||
cur = data = malloc(*bytes); | |||
/* Table */ | |||
cur += sprintf(cur, "<table cols='%d' cellpadding='0' cellspacing='0'>\n", | |||
@@ -593,14 +572,14 @@ static int export_html3(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
cur += sprintf(cur, "</table>\n"); | |||
/* Crop to really used size */ | |||
ex->size = (uintptr_t)(cur - ex->data); | |||
ex->data = realloc(ex->data, ex->size); | |||
*bytes = (uintptr_t)(cur - data); | |||
data = realloc(data, *bytes); | |||
return 0; | |||
return data; | |||
} | |||
/* Export a text file with IRC colours */ | |||
static int export_irc(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
static void *export_irc(cucul_canvas_t *cv, unsigned long int *bytes) | |||
{ | |||
static uint8_t const palette[] = | |||
{ | |||
@@ -608,7 +587,7 @@ static int export_irc(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
14, 12, 9, 11, 4, 13, 8, 0, /* Light */ | |||
}; | |||
char *cur; | |||
char *data, *cur; | |||
unsigned int x, y; | |||
/* 14 bytes assumed for max length per pixel. Worst case scenario: | |||
@@ -621,10 +600,8 @@ static int export_irc(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
* In real life, the average bytes per pixel value will be around 5. | |||
*/ | |||
ex->size = 2 + cv->height * (3 + cv->width * 14); | |||
ex->data = malloc(ex->size); | |||
cur = ex->data; | |||
*bytes = 2 + cv->height * (3 + cv->width * 14); | |||
cur = data = malloc(*bytes); | |||
for(y = 0; y < cv->height; y++) | |||
{ | |||
@@ -701,14 +678,14 @@ static int export_irc(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
} | |||
/* Crop to really used size */ | |||
ex->size = (uintptr_t)(cur - ex->data); | |||
ex->data = realloc(ex->data, ex->size); | |||
*bytes = (uintptr_t)(cur - data); | |||
data = realloc(data, *bytes); | |||
return 0; | |||
return data; | |||
} | |||
/* Export a PostScript document. */ | |||
static int export_ps(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
static void *export_ps(cucul_canvas_t *cv, unsigned long int *bytes) | |||
{ | |||
static char const *ps_header = | |||
"%!\n" | |||
@@ -735,14 +712,12 @@ static int export_ps(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
"gsave\n" | |||
"6 10 scale\n"; | |||
char *cur; | |||
char *data, *cur; | |||
unsigned int x, y; | |||
/* 200 is arbitrary but should be ok */ | |||
ex->size = strlen(ps_header) + 100 + cv->height * (32 + cv->width * 200); | |||
ex->data = malloc(ex->size); | |||
cur = ex->data; | |||
*bytes = strlen(ps_header) + 100 + cv->height * (32 + cv->width * 200); | |||
cur = data = malloc(*bytes); | |||
/* Header */ | |||
cur += sprintf(cur, "%s", ps_header); | |||
@@ -810,14 +785,14 @@ static int export_ps(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
cur += sprintf(cur, "showpage\n"); | |||
/* Crop to really used size */ | |||
ex->size = (uintptr_t)(cur - ex->data); | |||
ex->data = realloc(ex->data, ex->size); | |||
*bytes = (uintptr_t)(cur - data); | |||
data = realloc(data, *bytes); | |||
return 0; | |||
return data; | |||
} | |||
/* Export an SVG vector image */ | |||
static int export_svg(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
static void *export_svg(cucul_canvas_t *cv, unsigned long int *bytes) | |||
{ | |||
static char const svg_header[] = | |||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | |||
@@ -826,14 +801,12 @@ static int export_svg(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"" | |||
" xml:space=\"preserve\" version=\"1.1\" baseProfile=\"full\">\n"; | |||
char *cur; | |||
char *data, *cur; | |||
unsigned int x, y; | |||
/* 200 is arbitrary but should be ok */ | |||
ex->size = strlen(svg_header) + 128 + cv->width * cv->height * 200; | |||
ex->data = malloc(ex->size); | |||
cur = ex->data; | |||
*bytes = strlen(svg_header) + 128 + cv->width * cv->height * 200; | |||
cur = data = malloc(*bytes); | |||
/* Header */ | |||
cur += sprintf(cur, svg_header, cv->width * 6, cv->height * 10, | |||
@@ -896,33 +869,36 @@ static int export_svg(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
cur += sprintf(cur, "</svg>\n"); | |||
/* Crop to really used size */ | |||
ex->size = (uintptr_t)(cur - ex->data); | |||
ex->data = realloc(ex->data, ex->size); | |||
*bytes = (uintptr_t)(cur - data); | |||
data = realloc(data, *bytes); | |||
return 0; | |||
return data; | |||
} | |||
/* Export a TGA image */ | |||
static int export_tga(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
static void *export_tga(cucul_canvas_t *cv, unsigned long int *bytes) | |||
{ | |||
char const * const *fontlist; | |||
char * cur; | |||
char *data, *cur; | |||
cucul_font_t *f; | |||
unsigned int i, w, h; | |||
fontlist = cucul_get_font_list(); | |||
if(!fontlist[0]) | |||
return -1; | |||
{ | |||
#if defined(HAVE_ERRNO_H) | |||
errno = EINVAL; | |||
#endif | |||
return NULL; | |||
} | |||
f = cucul_load_font(fontlist[0], 0); | |||
w = cucul_get_canvas_width(cv) * cucul_get_font_width(f); | |||
h = cucul_get_canvas_height(cv) * cucul_get_font_height(f); | |||
ex->size = w * h * 4 + 18; /* 32 bpp + 18 bytes for the header */ | |||
ex->data = malloc(ex->size); | |||
cur = ex->data; | |||
*bytes = w * h * 4 + 18; /* 32 bpp + 18 bytes for the header */ | |||
cur = data = malloc(*bytes); | |||
/* ID Length */ | |||
cur += sprintf(cur, "%c", 0); | |||
@@ -957,6 +933,6 @@ static int export_tga(cucul_canvas_t *cv, cucul_buffer_t *ex) | |||
cucul_free_font(f); | |||
return 0; | |||
return data; | |||
} | |||
@@ -57,17 +57,18 @@ struct ansi_grcm | |||
uint8_t bold, negative, concealed; | |||
}; | |||
static cucul_canvas_t *import_caca(void const *, unsigned int); | |||
static cucul_canvas_t *import_text(void const *, unsigned int); | |||
static cucul_canvas_t *import_ansi(void const *, unsigned int, int); | |||
static long int import_caca(cucul_canvas_t *, void const *, unsigned int); | |||
static long int import_text(cucul_canvas_t *, void const *, unsigned int); | |||
static long int import_ansi(cucul_canvas_t *, void const *, unsigned int, int); | |||
static void ansi_parse_grcm(cucul_canvas_t *, struct ansi_grcm *, | |||
unsigned int, unsigned int const *); | |||
/** \brief Import a buffer into a canvas | |||
/** \brief Import a memory buffer into a canvas | |||
* | |||
* Import a libcucul buffer as returned by cucul_load_memory() | |||
* or cucul_load_file() into an internal libcucul canvas. | |||
* Import a memory buffer into the given libcucul canvas's current | |||
* frame. The current frame is resized accordingly and its contents are | |||
* replaced with the imported data. | |||
* | |||
* Valid values for \c format are: | |||
* - \c "": attempt to autodetect the file format. | |||
@@ -76,51 +77,51 @@ static void ansi_parse_grcm(cucul_canvas_t *, struct ansi_grcm *, | |||
* - \c "utf8": import UTF-8 files with ANSI colour codes. | |||
* - \c "caca": import native libcaca files. | |||
* | |||
* If an error occurs, NULL is returned and \b errno is set accordingly: | |||
* If an error occurs, -1 is returned and \b errno is set accordingly: | |||
* - \c ENOMEM Not enough memory to allocate canvas. | |||
* - \c EINVAL Invalid format requested. | |||
* | |||
* \param A libcucul canvas in which to import the file. | |||
* \param buffer A \e libcucul buffer containing the data to be loaded | |||
* into a canvas. | |||
* \param format A string describing the input format. | |||
* \return A libcucul canvas, or NULL in case of error. | |||
* \return The number of bytes read, or -1 if an error occurred. | |||
*/ | |||
cucul_canvas_t * cucul_import_canvas(cucul_buffer_t *buffer, char const *format) | |||
long int cucul_import(cucul_canvas_t *cv, unsigned char const *buf, | |||
unsigned long int len, char const *format) | |||
{ | |||
char const *buf = (char const*)buffer->data; | |||
if(!strcasecmp("caca", format)) | |||
return import_caca(buffer->data, buffer->size); | |||
return import_caca(cv, buf, len); | |||
if(!strcasecmp("utf8", format)) | |||
return import_ansi(buffer->data, buffer->size, 1); | |||
return import_ansi(cv, buf, len, 1); | |||
if(!strcasecmp("text", format)) | |||
return import_text(buffer->data, buffer->size); | |||
return import_text(cv, buf, len); | |||
if(!strcasecmp("ansi", format)) | |||
return import_ansi(buffer->data, buffer->size, 0); | |||
return import_ansi(cv, buf, len, 0); | |||
/* Autodetection */ | |||
if(!strcasecmp("", format)) | |||
{ | |||
unsigned int i; | |||
/* If 4 first letters are CACA */ | |||
if(buffer->size >= 4 && (uint8_t)buf[0] == 0xca && | |||
(uint8_t)buf[1] == 0xca && buf[2] == 'C' && buf[3] == 'V') | |||
return import_caca(buffer->data, buffer->size); | |||
/* If 4 first bytes are 0xcaca + 'CV' */ | |||
if(len >= 4 && buf[0] == 0xca && | |||
buf[1] == 0xca && buf[2] == 'C' && buf[3] == 'V') | |||
return import_caca(cv, buf, len); | |||
/* If we find ESC[ argv, we guess it's an ANSI file */ | |||
for(i = 0; i + 1 < buffer->size; i++) | |||
for(i = 0; i + 1 < len; i++) | |||
if((buf[i] == 0x1b) && (buf[i + 1] == '[')) | |||
return import_ansi(buffer->data, buffer->size, 0); | |||
return import_ansi(cv, buf, len, 0); | |||
/* Otherwise, import it as text */ | |||
return import_text(buffer->data, buffer->size); | |||
return import_text(cv, buf, len); | |||
} | |||
#if defined(HAVE_ERRNO_H) | |||
errno = EINVAL; | |||
#endif | |||
return NULL; | |||
return -1; | |||
} | |||
/** \brief Get available import formats | |||
@@ -152,13 +153,15 @@ char const * const * cucul_get_import_list(void) | |||
* XXX: the following functions are local. | |||
*/ | |||
static cucul_canvas_t *import_caca(void const *data, unsigned int size) | |||
static long int import_caca(cucul_canvas_t *cv, | |||
void const *data, unsigned int size) | |||
{ | |||
cucul_canvas_t *cv; | |||
uint8_t const *buf = (uint8_t const *)data; | |||
unsigned int control_size, data_size, full_size, frames, f, n; | |||
uint16_t version, flags; | |||
cucul_set_canvas_size(cv, 0, 0); | |||
if(size < 20) | |||
goto invalid_caca; | |||
@@ -197,16 +200,10 @@ static cucul_canvas_t *import_caca(void const *data, unsigned int size) | |||
goto invalid_caca; | |||
/* FIXME: read all frames, not only the first one */ | |||
cv = cucul_create_canvas(sscanu32(buf + 4 + 16), | |||
sscanu32(buf + 4 + 16 + 4)); | |||
cucul_set_canvas_size(cv, sscanu32(buf + 4 + 16), | |||
sscanu32(buf + 4 + 16 + 4)); | |||
if(!cv) | |||
{ | |||
#if defined(HAVE_ERRNO_H) | |||
errno = ENOMEM; | |||
#endif | |||
return NULL; | |||
} | |||
/* FIXME: check for return value */ | |||
for(n = sscanu32(buf + 4 + 16) * sscanu32(buf + 4 + 16 + 4); n--; ) | |||
{ | |||
@@ -216,30 +213,22 @@ static cucul_canvas_t *import_caca(void const *data, unsigned int size) | |||
cv->curattr = sscanu32(buf + 4 + 16 + 12); | |||
return cv; | |||
return size; | |||
invalid_caca: | |||
#if defined(HAVE_ERRNO_H) | |||
errno = EINVAL; | |||
#endif | |||
return NULL; | |||
return -1; | |||
} | |||
static cucul_canvas_t *import_text(void const *data, unsigned int size) | |||
static long int import_text(cucul_canvas_t *cv, | |||
void const *data, unsigned int size) | |||
{ | |||
cucul_canvas_t *cv; | |||
char const *text = (char const *)data; | |||
unsigned int width = 0, height = 0, x = 0, y = 0, i; | |||
cv = cucul_create_canvas(width, height); | |||
if(!cv) | |||
{ | |||
#if defined(HAVE_ERRNO_H) | |||
errno = ENOMEM; | |||
#endif | |||
return NULL; | |||
} | |||
cucul_set_canvas_size(cv, width, height); | |||
cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_TRANSPARENT); | |||
for(i = 0; i < size; i++) | |||
@@ -274,29 +263,20 @@ static cucul_canvas_t *import_text(void const *data, unsigned int size) | |||
if(y > height) | |||
cucul_set_canvas_size(cv, width, height = y); | |||
return cv; | |||
return size; | |||
} | |||
static cucul_canvas_t *import_ansi(void const *data, unsigned int size, | |||
int utf8) | |||
static long int import_ansi(cucul_canvas_t *cv, | |||
void const *data, unsigned int size, int utf8) | |||
{ | |||
struct ansi_grcm grcm; | |||
unsigned char const *buffer = (unsigned char const*)data; | |||
cucul_canvas_t *cv; | |||
unsigned int i, j, skip, dummy = 0; | |||
unsigned int width = 0, height = 0, wch = 1; | |||
unsigned long int ch; | |||
int x = 0, y = 0, save_x = 0, save_y = 0; | |||
cv = cucul_create_canvas(width, height); | |||
if(!cv) | |||
{ | |||
#if defined(HAVE_ERRNO_H) | |||
errno = ENOMEM; | |||
#endif | |||
return NULL; | |||
} | |||
cucul_set_canvas_size(cv, width, height); | |||
ansi_parse_grcm(cv, &grcm, 1, &dummy); | |||
for(i = 0; i < size; i += skip) | |||
@@ -494,7 +474,7 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size, | |||
cucul_set_canvas_size(cv, width, height = y); | |||
} | |||
return cv; | |||
return size; | |||
} | |||
/* XXX : ANSI loader helper */ | |||
@@ -12,13 +12,17 @@ | |||
*/ | |||
/* | |||
* This file contains buffer handling functions. | |||
* This file contains legacy functions that we keep around until all | |||
* applications are ported. | |||
*/ | |||
#include "config.h" | |||
#include "common.h" | |||
#if !defined(__KERNEL__) | |||
# if defined(HAVE_ERRNO_H) | |||
# include <errno.h> | |||
# endif | |||
# include <stdio.h> | |||
# include <stdlib.h> | |||
# include <string.h> | |||
@@ -27,22 +31,71 @@ | |||
#include "cucul.h" | |||
#include "cucul_internals.h" | |||
/** \brief Load a memory area into a buffer. | |||
* | |||
* Create a \e libcucul buffer that points to the given memory area. The | |||
* data is not duplicated and any changes made to the original memory area | |||
* will appear in the buffer. | |||
* | |||
* Keep in mind that buffers are not strings. When loading a C string, the | |||
* terminating '\\0' must not be part of the buffer, hence \e size should | |||
* be computed with strlen(). Conversely, the '\\0' is not appended to | |||
* exported buffers even when they could be parsed as strings. | |||
* | |||
* \param data The memory area to load. | |||
* \param size The size of the memory area. | |||
* \return A \e libcucul buffer pointing to the memory area, or NULL | |||
* if an error occurred. | |||
/* | |||
* Functions from color.c | |||
*/ | |||
int cucul_set_color(cucul_canvas_t *cv, unsigned char fg, unsigned char bg) | |||
{ | |||
return cucul_set_color_ansi(cv, fg, bg); | |||
} | |||
int cucul_set_truecolor(cucul_canvas_t *cv, unsigned int fg, unsigned int bg) | |||
{ | |||
return cucul_set_color_argb(cv, fg, bg); | |||
} | |||
/* | |||
* Functions from import.c | |||
*/ | |||
cucul_canvas_t * cucul_import_canvas(cucul_buffer_t *buf, char const *format) | |||
{ | |||
cucul_canvas_t *cv = cucul_create_canvas(0, 0); | |||
int ret = cucul_import(cv, (unsigned char const *)buf->data, | |||
buf->size, format); | |||
if(ret < 0) | |||
{ | |||
cucul_free_canvas(cv); | |||
return NULL; | |||
} | |||
return cv; | |||
} | |||
/* | |||
* Functions from export.c | |||
*/ | |||
cucul_buffer_t * cucul_export_canvas(cucul_canvas_t *cv, char const *format) | |||
{ | |||
cucul_buffer_t *ex; | |||
ex = malloc(sizeof(cucul_buffer_t)); | |||
if(!ex) | |||
{ | |||
#if defined(HAVE_ERRNO_H) | |||
errno = ENOMEM; | |||
#endif | |||
return NULL; | |||
} | |||
ex->data = cucul_export(cv, format, &ex->size); | |||
if(!ex->data) | |||
{ | |||
free(ex); | |||
return NULL; | |||
} | |||
ex->user_data = 0; | |||
return ex; | |||
} | |||
/* | |||
* Functions from buffer.c | |||
*/ | |||
cucul_buffer_t *cucul_load_memory(void *data, unsigned long int size) | |||
{ | |||
cucul_buffer_t *buf; | |||
@@ -58,15 +111,6 @@ cucul_buffer_t *cucul_load_memory(void *data, unsigned long int size) | |||
return buf; | |||
} | |||
/** \brief Load a file into a buffer. | |||
* | |||
* Load a file into memory and returns a \e libcucul buffer for use with | |||
* other functions. | |||
* | |||
* \param file The filename | |||
* \return A \e libcucul buffer containing the file's contents, or NULL | |||
* if an error occurred. | |||
*/ | |||
#if !defined(__KERNEL__) | |||
cucul_buffer_t *cucul_load_file(char const *file) | |||
{ | |||
@@ -105,45 +149,17 @@ cucul_buffer_t *cucul_load_file(char const *file) | |||
return buf; | |||
} | |||
#endif | |||
/** \brief Get the buffer size. | |||
* | |||
* Return the length (in bytes) of the memory area stored in the given | |||
* \e libcucul buffer. | |||
* | |||
* This function never fails. | |||
* | |||
* \param buf A \e libcucul buffer | |||
* \return The buffer data length. | |||
*/ | |||
unsigned long int cucul_get_buffer_size(cucul_buffer_t *buf) | |||
{ | |||
return buf->size; | |||
} | |||
/** \brief Get the buffer data. | |||
* | |||
* Get a pointer to the memory area stored in the given | |||
* \e libcucul buffer. | |||
* | |||
* This function never fails. | |||
* | |||
* \param buf A \e libcucul buffer | |||
* \return A pointer to the buffer memory area. | |||
*/ | |||
void * cucul_get_buffer_data(cucul_buffer_t *buf) | |||
{ | |||
return buf->data; | |||
} | |||
/** \brief Free a buffer. | |||
* | |||
* Free the structures associated with the given \e libcucul buffer. | |||
* | |||
* This function never fails. | |||
* | |||
* \param buf A \e libcucul buffer | |||
* \return This function always returns 0. | |||
*/ | |||
int cucul_free_buffer(cucul_buffer_t *buf) | |||
{ | |||
if(!buf->user_data) |