From c871efa627592871f6160763e04e4405c4842c61 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Mon, 22 Apr 2024 18:00:15 +0200 Subject: [PATCH] xschem image rectangles: allow to fetch urls using filter="tcleval(wget --quiet http://.... -O -)" and image="" --- src/draw.c | 84 +++++++++++++++++++++++++------------------------ src/editprop.c | 2 +- src/save.c | 10 +++--- src/scheduler.c | 1 + 4 files changed, 51 insertions(+), 46 deletions(-) diff --git a/src/draw.c b/src/draw.c index 128e841a..c297ed44 100644 --- a/src/draw.c +++ b/src/draw.c @@ -4102,37 +4102,39 @@ static cairo_surface_t *get_surface_from_file(const char *filename, const char * unsigned char **buffer, size_t *size) { int jpg = 0; - png_to_byte_closure_t closure; + png_to_byte_closure_t closure = {NULL, 0L, 0L}; size_t filesize = 0; char *filedata = NULL; FILE *fd; struct stat buf; cairo_surface_t *surface = NULL; - if(stat(filename, &buf)) { - dbg(0, "get_surface_from_file(): file %s not found.\n", filename); - *buffer = NULL; - *size = 0; - return NULL; - } - filesize = (size_t)buf.st_size; - if(filesize > 0) { - fd = fopen(filename, fopen_read_mode); - if(fd) { - size_t bytes_read; - filedata = my_malloc(_ALLOC_ID_, filesize); - if((bytes_read = fread(filedata, 1, filesize, fd)) < filesize) { - filesize = bytes_read; - dbg(0, "get_surface_from_file(): less bytes read than expected from %s, got %ld bytes\n", - filename, bytes_read); - } - fclose(fd); + if(filename[0]) { + if(stat(filename, &buf)) { + dbg(0, "get_surface_from_file(): file %s not found.\n", filename); + *buffer = NULL; + *size = 0; + return NULL; + } + filesize = (size_t)buf.st_size; + if(filesize > 0) { + fd = fopen(filename, fopen_read_mode); + if(fd) { + size_t bytes_read; + filedata = my_malloc(_ALLOC_ID_, filesize); + if((bytes_read = fread(filedata, 1, filesize, fd)) < filesize) { + filesize = bytes_read; + dbg(0, "get_surface_from_file(): less bytes read than expected from %s, got %ld bytes\n", + filename, bytes_read); + } + fclose(fd); + } + } else { + dbg(0, "get_surface_from_file(): file %s has zero size\n", filename); + *buffer = NULL; + *size = 0; + return NULL; } - } else { - dbg(0, "get_surface_from_file(): file %s has zero size\n", filename); - *buffer = NULL; - *size = 0; - return NULL; } if(filter) { size_t filtered_img_size = 0; @@ -4157,22 +4159,22 @@ static cairo_surface_t *get_surface_from_file(const char *filename, const char * } else { jpg = -1; } - - if(jpg == 0) { - surface = cairo_image_surface_create_from_png_stream(png_reader, &closure); - } else if(jpg == 1) { - #if defined(HAS_LIBJPEG) - surface = cairo_image_surface_create_from_jpeg_mem(closure.buffer, closure.size); - #endif - } - - if(!surface || cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { - if(jpg != 1) dbg(0, "draw_image(): failure creating image surface from %s\n", filename); - if(surface) cairo_surface_destroy(surface); - my_free(_ALLOC_ID_, &closure.buffer); - *buffer = NULL; - *size = 0; - return NULL; + if(closure.buffer) { + if(jpg == 0) { + surface = cairo_image_surface_create_from_png_stream(png_reader, &closure); + } else if(jpg == 1) { + #if defined(HAS_LIBJPEG) + surface = cairo_image_surface_create_from_jpeg_mem(closure.buffer, closure.size); + #endif + } + if(!surface || cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { + if(jpg != 1) dbg(0, "draw_image(): failure creating image surface from %s\n", filename); + if(surface) cairo_surface_destroy(surface); + my_free(_ALLOC_ID_, &closure.buffer); + *buffer = NULL; + *size = 0; + return NULL; + } } *buffer = closure.buffer; *size = closure.size; @@ -4257,7 +4259,7 @@ int draw_image(int dr, xRect *r, double *x1, double *y1, double *x2, double *y2, return 0; } /******* ... or read PNG from file (image attribute) *******/ - } else if(filename[0]) { + } else if(1 || filename[0]) { unsigned char *buffer = NULL; size_t size = 0; char *filter = NULL; diff --git a/src/editprop.c b/src/editprop.c index 6c0c4d82..fe33e6e9 100644 --- a/src/editprop.c +++ b/src/editprop.c @@ -911,7 +911,7 @@ static int edit_rect_property(int x) my_strdup(_ALLOC_ID_, &xctx->rect[c][n].prop_ptr, (char *) tclgetvar("retval")); } - set_rect_flags(&xctx->rect[c][n]); /* set cached .flags bitmask from on attributes */ + set_rect_flags(&xctx->rect[c][n]); /* set cached .flags bitmask from attributes */ set_rect_extraptr(0, &xctx->rect[c][n]); diff --git a/src/save.c b/src/save.c index 7a6793a9..0ccfea66 100644 --- a/src/save.c +++ b/src/save.c @@ -69,7 +69,7 @@ int filter_data(const char *din, const size_t ilen, pid_t pid; size_t bufsize = 32768, oalloc = 0, n = 0; - if(!din || !ilen || !cmd) { /* basic check */ + if(!cmd) { /* basic check */ *dout = NULL; *olen = 0; return 1; @@ -136,9 +136,11 @@ int filter_data(const char *din, const size_t ilen, /* parent */ close(p1[0]); /*only write to p1 */ close(p2[1]); /* only read from p2 */ - if(write(p1[1], din, ilen) != ilen) { /* write input data to pipe */ - fprintf(stderr, "filter_data() write to pipe failed or not completed\n"); - ret = 1; + if(din && ilen) { + if(write(p1[1], din, ilen) != ilen) { /* write input data to pipe */ + fprintf(stderr, "filter_data() write to pipe failed or not completed\n"); + ret = 1; + } } fsync(p1[1]); close(p1[1]); diff --git a/src/scheduler.c b/src/scheduler.c index 09160988..5b6d0112 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -5187,6 +5187,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } if(change_done) set_modify(1); set_rect_flags(r); /* set cached .flags bitmask from attributes */ + set_rect_extraptr(0, &xctx->rect[c][n]); if(!fast) { bbox(ADD, r->x1, r->y1, r->x2, r->y2); /* redraw rect with new props */