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;
|
||||
const char *ptr;
|
||||
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->enable_layer[GRIDLAYER]) for(i = 0; i < xctx->rects[GRIDLAYER]; i++) {
|
||||
|
|
@ -2428,11 +2429,13 @@ int draw_images_all(void)
|
|||
if(r->flags & 1024) {
|
||||
struct stat buf;
|
||||
const char *attr;
|
||||
const char *filename;
|
||||
double scalex, scaley;
|
||||
char *filter = NULL;
|
||||
png_to_byte_closure_t closure;
|
||||
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) {
|
||||
bbox_set = 1;
|
||||
save_bbx1 = xctx->bbx1;
|
||||
|
|
@ -2461,7 +2464,16 @@ int draw_images_all(void)
|
|||
/* ... or read PNG from image_data attribute */
|
||||
} else if( (attr = get_tok_value(r->prop_ptr, "image_data", 0))[0] ) {
|
||||
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.size = data_size; /* should not be necessary */
|
||||
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);
|
||||
dbg(1, "draw_images_all(): length2 = %d\n", closure.pos);
|
||||
/* ... 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;
|
||||
size_t olength;
|
||||
emb_ptr->image = cairo_image_surface_create_from_png(filename);
|
||||
if(cairo_surface_status(emb_ptr->image) != CAIRO_STATUS_SUCCESS) return 1;
|
||||
/* write PNG to in-memory buffer */
|
||||
closure.buffer = NULL;
|
||||
closure.size = 0;
|
||||
closure.pos = 0;
|
||||
cairo_surface_write_to_png_stream(emb_ptr->image, png_writer, &closure);
|
||||
dbg(1, "draw_images_all(): length3 = %d\n", closure.pos);
|
||||
/* put base64 encoded data to rect image_data attrinute */
|
||||
image_data = base64_encode(closure.buffer, closure.pos, &olength, 0);
|
||||
if(filter) {
|
||||
size_t filtersize = 0;
|
||||
char *filterdata = NULL;
|
||||
size_t pngsize = 0;
|
||||
char *pngdata = NULL;
|
||||
struct stat st;
|
||||
if(stat(filename, &st) == 0 /* && ( (st.st_mode & S_IFMT) == S_IFREG)*/ ) {
|
||||
FILE *fd;
|
||||
filtersize = st.st_size;
|
||||
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);
|
||||
/* 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_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 {
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -2532,6 +2573,7 @@ int draw_images_all(void)
|
|||
if(rescaled) bbox(ADD, r->x1, r->y1, r->x2, r->y2);
|
||||
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;
|
||||
pid_t pid;
|
||||
size_t bufsize = 1024, oalloc = 0, n = 0;
|
||||
|
||||
if(!din || !ilen || !cmd) { /* basic check */
|
||||
*dout = NULL;
|
||||
*olen = 0;
|
||||
return 1;
|
||||
}
|
||||
pipe(p1);
|
||||
pipe(p2);
|
||||
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]);
|
||||
if(n < 0 || !*olen) {
|
||||
if(oalloc) {
|
||||
my_free(1483, *dout);
|
||||
my_free(1483, dout);
|
||||
*olen = 0;
|
||||
}
|
||||
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 */
|
||||
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[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'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 */
|
||||
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] = {
|
||||
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') {
|
||||
if(!strcmp(argv[1],"test"))
|
||||
{
|
||||
char *odata = NULL;
|
||||
size_t olen;
|
||||
cmd_found = 1;
|
||||
if(!filter_data("stefan.", 7, &odata, &olen, "base64")) {
|
||||
dbg(0, "odata=%s, olen=%d\n", odata, olen);
|
||||
}
|
||||
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 int set_rect_flags(xRect *r);
|
||||
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 char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length, int brk);
|
||||
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, const size_t input_length, size_t *output_length, int brk);
|
||||
extern int get_raw_index(const char *node);
|
||||
extern void free_rawfile(int dr);
|
||||
extern int read_rawfile(const char *f);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue