From c342a1c41fa1ed188e9f913d135b8f397327893d Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Mon, 28 Oct 2024 18:55:13 +0100 Subject: [PATCH] update svgdraw and psprint to recognize svg embedded images. svgdraw exports it as embedded svg --- src/draw.c | 2 +- src/psprint.c | 28 ++++++++++++++++++++-------- src/svgdraw.c | 39 ++++++++++++++++++++++++++++++--------- src/xschem.h | 1 + 4 files changed, 52 insertions(+), 18 deletions(-) diff --git a/src/draw.c b/src/draw.c index a8b686fb..1b984065 100644 --- a/src/draw.c +++ b/src/draw.c @@ -4229,7 +4229,7 @@ int edit_image(int what, xRect *r) * The return value is a pointer to the beginning of the sub-string, or * NULL if the substring is not found. */ -static void *my_memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen) +void *my_memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen) { int needle_first; const char *p = haystack; diff --git a/src/psprint.c b/src/psprint.c index 2071abc8..7adcd09c 100644 --- a/src/psprint.c +++ b/src/psprint.c @@ -85,14 +85,15 @@ static int ps_embedded_image(xRect* r, double x1, double y1, double x2, double y unsigned char *ptr = NULL; int invertImage; unsigned char* ascii85EncodedJpeg; - const char* attr; + char *attr = NULL; + unsigned char *buffer = NULL; cairo_surface_t *surface = NULL, *orig_sfc = NULL; xEmb_image *emb_ptr; unsigned char* jpgData = NULL; size_t fileSize = 0; int quality=40; - const char *quality_attr; - size_t oLength, attr_len; + const char *quality_attr, *filter; + size_t oLength, attr_len, buffer_size; cairo_t *ct; double sx1, sy1, sx2, sy2; @@ -113,17 +114,26 @@ static int ps_embedded_image(xRect* r, double x1, double y1, double x2, double y quality_attr = get_tok_value(r->prop_ptr, "jpg_quality", 0); if(quality_attr[0]) quality = atoi(quality_attr); } - attr = get_tok_value(r->prop_ptr, "image_data", 0); - attr_len = strlen(attr); + attr_len = my_strdup2(_ALLOC_ID_, &attr, get_tok_value(r->prop_ptr, "image_data", 0)); + filter = get_tok_value(r->prop_ptr, "filter", 0); + buffer = base64_decode(attr, attr_len, &buffer_size); if(attr_len > 5) { - if(!strncmp(attr, "/9j/", 4)) jpg = 1; - else if(!strncmp(attr, "iVBOR", 5)) jpg = 0; + if(!strncmp(attr, "/9j/", 4)) jpg = 1; /* jpg */ + else if(!strncmp(attr, "iVBOR", 5)) jpg = 0; /* png */ + else if(my_memmem(buffer, buffer_size, "extraptr; if(jpg == -1 || !(emb_ptr && emb_ptr->image)) { + my_free(_ALLOC_ID_, &buffer); + my_free(_ALLOC_ID_, &attr); return 0; } orig_sfc = emb_ptr->image; @@ -164,7 +174,7 @@ static int ps_embedded_image(xRect* r, double x1, double y1, double x2, double y ptr[i + 0] = b; } cairo_surface_mark_dirty(surface); - if(invertImage || jpg == 0) { + if(invertImage || jpg != 1) { cairo_image_surface_write_to_jpeg_mem(surface, &jpgData, &fileSize, quality); } else { jpgData = base64_decode(attr, attr_len, &fileSize); @@ -234,6 +244,8 @@ static int ps_embedded_image(xRect* r, double x1, double y1, double x2, double y fprintf(fd, "grestore\n"); my_free(_ALLOC_ID_, &ascii85EncodedJpeg); free(jpgData); + my_free(_ALLOC_ID_, &buffer); + my_free(_ALLOC_ID_, &attr); #endif return 1; } diff --git a/src/svgdraw.c b/src/svgdraw.c index 08b23e0b..47a21286 100644 --- a/src/svgdraw.c +++ b/src/svgdraw.c @@ -468,13 +468,16 @@ static void svg_drawgrid() static int svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, double ry2, int rot, int flip) { - const char *attr; + char *attr = NULL; + const char *alpha_str, *filter; size_t attr_len; double x1, y1, x2, y2, w, h, scalex = 1.0, scaley = 1.0; int jpg = 0; char opacity[100]; char transform[150]; double alpha = 1.0; + unsigned char *buffer = NULL; + size_t buffer_size; x1=X_TO_SCREEN(rx1); y1=Y_TO_SCREEN(ry1); @@ -496,28 +499,46 @@ static int svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, doub if(flip && (rot == 0 || rot == 2)) scalex = -1.0; else if(flip && (rot == 1 || rot == 3)) scaley = -1.0; - attr = get_tok_value(r->prop_ptr, "alpha", 0); - if(attr[0]) alpha = atof(attr); - attr = get_tok_value(r->prop_ptr, "image_data", 0); - attr_len = strlen(attr); - + alpha_str = get_tok_value(r->prop_ptr, "alpha", 0); + if(alpha_str[0]) alpha = atof(alpha_str); + attr_len = my_strdup2(_ALLOC_ID_, &attr, get_tok_value(r->prop_ptr, "image_data", 0)); + buffer = base64_decode(attr, attr_len, &buffer_size); + filter = get_tok_value(r->prop_ptr, "filter", 0); if(attr_len > 5) { if(!strncmp(attr, "/9j/", 4)) jpg = 1; else if(!strncmp(attr, "iVBOR", 5)) jpg = 0; + + else if(my_memmem(buffer, buffer_size, "\n", - 0.0, 0.0, w, h, transform, opacity, jpg ? "jpeg" : "png", attr); + /* png jpg */ + if(jpg == 0 || jpg == 1) { + fprintf(fd, "\n", + 0.0, 0.0, w, h, transform, opacity, jpg ? "jpeg" : "png", attr); + } else if(jpg == 2) { /* svg */ + fprintf(fd, "\n", + 0.0, 0.0, w, h, transform, opacity, attr); + } + my_free(_ALLOC_ID_, &buffer); + my_free(_ALLOC_ID_, &attr); return 1; } diff --git a/src/xschem.h b/src/xschem.h index 7367689a..7ed3e5d4 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1630,6 +1630,7 @@ extern char *my_free(int id, void *ptr); extern size_t my_strcat(int id, char **, const char *); extern size_t my_strcat2(int id, char **, const char *); extern size_t my_mstrcat(int id, char **str, const char *append_str, ...); +extern void *my_memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen); extern char *my_itoa(int i); extern double atof_spice(const char *s); extern double atof_eng(const char *s); /* same as atof_spice, but recognizes 'M' as Mega and 'm' as Milli */