allow embedding all image formats if a xxx-->png filter shell command is provided as attribute
This commit is contained in:
parent
90f1a00a6f
commit
c8ec7a77f2
68
src/draw.c
68
src/draw.c
|
|
@ -2421,6 +2421,7 @@ int draw_images_all(void)
|
||||||
double sx1, sy1, sx2, sy2, alpha;
|
double sx1, sy1, sx2, sy2, alpha;
|
||||||
const char *ptr;
|
const char *ptr;
|
||||||
int save_bbx1, save_bby1, save_bbx2, save_bby2;
|
int save_bbx1, save_bby1, save_bbx2, save_bby2;
|
||||||
|
char filename[PATH_MAX];
|
||||||
|
|
||||||
if(xctx->draw_single_layer==-1 || GRIDLAYER == xctx->draw_single_layer) {
|
if(xctx->draw_single_layer==-1 || GRIDLAYER == xctx->draw_single_layer) {
|
||||||
if(xctx->enable_layer[GRIDLAYER]) for(i = 0; i < xctx->rects[GRIDLAYER]; i++) {
|
if(xctx->enable_layer[GRIDLAYER]) for(i = 0; i < xctx->rects[GRIDLAYER]; i++) {
|
||||||
|
|
@ -2428,11 +2429,13 @@ int draw_images_all(void)
|
||||||
if(r->flags & 1024) {
|
if(r->flags & 1024) {
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
const char *attr;
|
const char *attr;
|
||||||
const char *filename;
|
|
||||||
double scalex, scaley;
|
double scalex, scaley;
|
||||||
|
char *filter = NULL;
|
||||||
png_to_byte_closure_t closure;
|
png_to_byte_closure_t closure;
|
||||||
xEmb_image *emb_ptr;
|
xEmb_image *emb_ptr;
|
||||||
|
|
||||||
|
my_strncpy(filename, get_tok_value(r->prop_ptr, "image", 0), S(filename));
|
||||||
|
my_strdup(1484, &filter, get_tok_value(r->prop_ptr, "filter", 0));
|
||||||
if(xctx->sem) {
|
if(xctx->sem) {
|
||||||
bbox_set = 1;
|
bbox_set = 1;
|
||||||
save_bbx1 = xctx->bbx1;
|
save_bbx1 = xctx->bbx1;
|
||||||
|
|
@ -2461,7 +2464,16 @@ int draw_images_all(void)
|
||||||
/* ... or read PNG from image_data attribute */
|
/* ... or read PNG from image_data attribute */
|
||||||
} else if( (attr = get_tok_value(r->prop_ptr, "image_data", 0))[0] ) {
|
} else if( (attr = get_tok_value(r->prop_ptr, "image_data", 0))[0] ) {
|
||||||
size_t data_size;
|
size_t data_size;
|
||||||
closure.buffer = base64_decode(attr, strlen(attr), &data_size);
|
if(filter) {
|
||||||
|
size_t filtersize = 0;
|
||||||
|
char *filterdata = NULL;
|
||||||
|
closure.buffer = NULL;
|
||||||
|
filterdata = (char *)base64_decode(attr, strlen(attr), &filtersize);
|
||||||
|
filter_data(filterdata, filtersize, (char **)&closure.buffer, &data_size, filter);
|
||||||
|
my_free(1488, &filterdata);
|
||||||
|
} else {
|
||||||
|
closure.buffer = base64_decode(attr, strlen(attr), &data_size);
|
||||||
|
}
|
||||||
closure.pos = 0;
|
closure.pos = 0;
|
||||||
closure.size = data_size; /* should not be necessary */
|
closure.size = data_size; /* should not be necessary */
|
||||||
emb_ptr->image = cairo_image_surface_create_from_png_stream(png_reader, &closure);
|
emb_ptr->image = cairo_image_surface_create_from_png_stream(png_reader, &closure);
|
||||||
|
|
@ -2469,22 +2481,51 @@ int draw_images_all(void)
|
||||||
my_free(1467, &closure.buffer);
|
my_free(1467, &closure.buffer);
|
||||||
dbg(1, "draw_images_all(): length2 = %d\n", closure.pos);
|
dbg(1, "draw_images_all(): length2 = %d\n", closure.pos);
|
||||||
/* ... or read PNG from file (image attribute) */
|
/* ... or read PNG from file (image attribute) */
|
||||||
} else if( (filename = get_tok_value(r->prop_ptr, "image", 0))[0] && !stat(filename, &buf)) {
|
} else if(filename[0] && !stat(filename, &buf)) {
|
||||||
char *image_data = NULL;
|
char *image_data = NULL;
|
||||||
size_t olength;
|
size_t olength;
|
||||||
emb_ptr->image = cairo_image_surface_create_from_png(filename);
|
if(filter) {
|
||||||
if(cairo_surface_status(emb_ptr->image) != CAIRO_STATUS_SUCCESS) return 1;
|
size_t filtersize = 0;
|
||||||
/* write PNG to in-memory buffer */
|
char *filterdata = NULL;
|
||||||
closure.buffer = NULL;
|
size_t pngsize = 0;
|
||||||
closure.size = 0;
|
char *pngdata = NULL;
|
||||||
closure.pos = 0;
|
struct stat st;
|
||||||
cairo_surface_write_to_png_stream(emb_ptr->image, png_writer, &closure);
|
if(stat(filename, &st) == 0 /* && ( (st.st_mode & S_IFMT) == S_IFREG)*/ ) {
|
||||||
dbg(1, "draw_images_all(): length3 = %d\n", closure.pos);
|
FILE *fd;
|
||||||
/* put base64 encoded data to rect image_data attrinute */
|
filtersize = st.st_size;
|
||||||
image_data = base64_encode(closure.buffer, closure.pos, &olength, 0);
|
if(filtersize) {
|
||||||
|
fd = fopen(filename, "r");
|
||||||
|
if(fd) {
|
||||||
|
filterdata = my_malloc(1490, filtersize);
|
||||||
|
fread(filterdata, filtersize, 1, fd);
|
||||||
|
fclose(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filter_data(filterdata, filtersize, &pngdata, &pngsize, filter);
|
||||||
|
closure.buffer = (unsigned char *)pngdata;
|
||||||
|
closure.size = pngsize;
|
||||||
|
closure.pos = 0;
|
||||||
|
emb_ptr->image = cairo_image_surface_create_from_png_stream(png_reader, &closure);
|
||||||
|
image_data = base64_encode((unsigned char *)filterdata, filtersize, &olength, 0);
|
||||||
|
my_free(1489, &filterdata);
|
||||||
|
} else {
|
||||||
|
closure.buffer = NULL;
|
||||||
|
closure.size = 0;
|
||||||
|
closure.pos = 0;
|
||||||
|
emb_ptr->image = cairo_image_surface_create_from_png(filename);
|
||||||
|
/* write PNG to in-memory buffer */
|
||||||
|
cairo_surface_write_to_png_stream(emb_ptr->image, png_writer, &closure);
|
||||||
|
image_data = base64_encode(closure.buffer, closure.pos, &olength, 0);
|
||||||
|
}
|
||||||
my_free(1468, &closure.buffer);
|
my_free(1468, &closure.buffer);
|
||||||
|
/* put base64 encoded data to rect image_data attrinute */
|
||||||
my_strdup2(1473, &r->prop_ptr, subst_token(r->prop_ptr, "image_data", image_data));
|
my_strdup2(1473, &r->prop_ptr, subst_token(r->prop_ptr, "image_data", image_data));
|
||||||
my_free(1474, &image_data);
|
my_free(1474, &image_data);
|
||||||
|
|
||||||
|
|
||||||
|
if(cairo_surface_status(emb_ptr->image) != CAIRO_STATUS_SUCCESS) return 1;
|
||||||
|
dbg(1, "draw_images_all(): length3 = %d\n", closure.pos);
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -2532,6 +2573,7 @@ int draw_images_all(void)
|
||||||
if(rescaled) bbox(ADD, r->x1, r->y1, r->x2, r->y2);
|
if(rescaled) bbox(ADD, r->x1, r->y1, r->x2, r->y2);
|
||||||
bbox(SET, 0.0, 0.0, 0.0, 0.0);
|
bbox(SET, 0.0, 0.0, 0.0, 0.0);
|
||||||
}
|
}
|
||||||
|
my_free(1486, &filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
src/save.c
12
src/save.c
|
|
@ -38,6 +38,12 @@ int filter_data(const char *din, const size_t ilen,
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
size_t bufsize = 1024, oalloc = 0, n = 0;
|
size_t bufsize = 1024, oalloc = 0, n = 0;
|
||||||
|
|
||||||
|
if(!din || !ilen || !cmd) { /* basic check */
|
||||||
|
*dout = NULL;
|
||||||
|
*olen = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
pipe(p1);
|
pipe(p1);
|
||||||
pipe(p2);
|
pipe(p2);
|
||||||
signal(SIGPIPE, SIG_IGN); /* so attempting write/read a broken pipe won't kill program */
|
signal(SIGPIPE, SIG_IGN); /* so attempting write/read a broken pipe won't kill program */
|
||||||
|
|
@ -87,7 +93,7 @@ int filter_data(const char *din, const size_t ilen,
|
||||||
close(p2[0]);
|
close(p2[0]);
|
||||||
if(n < 0 || !*olen) {
|
if(n < 0 || !*olen) {
|
||||||
if(oalloc) {
|
if(oalloc) {
|
||||||
my_free(1483, *dout);
|
my_free(1483, dout);
|
||||||
*olen = 0;
|
*olen = 0;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "no data read\n");
|
fprintf(stderr, "no data read\n");
|
||||||
|
|
@ -99,7 +105,7 @@ int filter_data(const char *din, const size_t ilen,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Caller should free returned buffer */
|
/* Caller should free returned buffer */
|
||||||
char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length, int brk) {
|
char *base64_encode(const unsigned char *data, const size_t input_length, size_t *output_length, int brk) {
|
||||||
static const char b64_enc[] = {
|
static const char b64_enc[] = {
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
|
|
@ -150,7 +156,7 @@ char *base64_encode(const unsigned char *data, size_t input_length, size_t *outp
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Caller should free returned buffer */
|
/* Caller should free returned buffer */
|
||||||
unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length) {
|
unsigned char *base64_decode(const char *data, const size_t input_length, size_t *output_length) {
|
||||||
static const unsigned char b64_dec[256] = {
|
static const unsigned char b64_dec[256] = {
|
||||||
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||||||
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||||||
|
|
|
||||||
|
|
@ -2670,12 +2670,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
||||||
else if(argv[1][0] == 't') {
|
else if(argv[1][0] == 't') {
|
||||||
if(!strcmp(argv[1],"test"))
|
if(!strcmp(argv[1],"test"))
|
||||||
{
|
{
|
||||||
char *odata = NULL;
|
|
||||||
size_t olen;
|
|
||||||
cmd_found = 1;
|
cmd_found = 1;
|
||||||
if(!filter_data("stefan.", 7, &odata, &olen, "base64")) {
|
|
||||||
dbg(0, "odata=%s, olen=%d\n", odata, olen);
|
|
||||||
}
|
|
||||||
Tcl_ResetResult(interp);
|
Tcl_ResetResult(interp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1008,8 +1008,8 @@ extern int read_embedded_rawfile(void);
|
||||||
extern char *base64_from_file(const char *f, size_t *length);
|
extern char *base64_from_file(const char *f, size_t *length);
|
||||||
extern int set_rect_flags(xRect *r);
|
extern int set_rect_flags(xRect *r);
|
||||||
extern int set_rect_extraptr(int what, xRect *drptr, xRect *srptr);
|
extern int set_rect_extraptr(int what, xRect *drptr, xRect *srptr);
|
||||||
extern unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length);
|
extern unsigned char *base64_decode(const char *data, const size_t input_length, size_t *output_length);
|
||||||
extern char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length, int brk);
|
extern char *base64_encode(const unsigned char *data, const size_t input_length, size_t *output_length, int brk);
|
||||||
extern int get_raw_index(const char *node);
|
extern int get_raw_index(const char *node);
|
||||||
extern void free_rawfile(int dr);
|
extern void free_rawfile(int dr);
|
||||||
extern int read_rawfile(const char *f);
|
extern int read_rawfile(const char *f);
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue