fixed filter_data routine that was clobbering ps export file, now ps output is correct without the need to add fflush() functions, that are thus removed in psprint.c

This commit is contained in:
stefan schippers 2023-01-18 00:24:28 +01:00
parent af0ddb76f0
commit 03b2b8652e
4 changed files with 68 additions and 34 deletions

View File

@ -24,9 +24,6 @@
#define X_TO_PS(x) ( (x+xctx->xorigin)* xctx->mooz )
#define Y_TO_PS(y) ( (y+xctx->yorigin)* xctx->mooz )
/* FIXME This must be investigated, without some fflushes the ps file is corrupted */
#define FFLUSH_PS
#if 0
* /* FIXME: overflow check. Not used, BTW */
* static char *strreplace(char s[], char token[], char replace[])
@ -129,24 +126,24 @@ unsigned char* bin2hex(const unsigned char* bin, size_t len)
void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2, int rot, int flip)
{
int i;
size_t data_size;
png_to_byte_closure_t closure;
size_t data_size = 0;
png_to_byte_closure_t closure = {NULL, 0, 0};
char* filter = NULL;
int png_size_x, png_size_y;
unsigned char *png_data, BG_r, BG_g, BG_b;
unsigned char *png_data = NULL, BG_r, BG_g, BG_b;
int invertImage;
/* static char str[PATH_MAX];
* FILE* fp;
*/
unsigned char* hexEncodedJPG;
unsigned char* hexEncodedJPG = NULL;
char* image_data64_ptr = NULL;
cairo_surface_t* surface;
cairo_surface_t* surface = NULL;
unsigned char* jpgData = NULL;
size_t fileSize = 0;
my_strdup(59, &filter, get_tok_value(r->prop_ptr, "filter", 0));
my_strdup2(1183, &image_data64_ptr, get_tok_value(r->prop_ptr, "image_data", 0));
if (filter) {
size_t filtersize = 0;
char* filterdata = NULL;
@ -163,6 +160,7 @@ void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2, int rot, i
closure.pos = 0;
closure.size = data_size; /* should not be necessary */
surface = cairo_image_surface_create_from_png_stream(png_reader, &closure);
png_size_x = cairo_image_surface_get_width(surface);
png_size_y = cairo_image_surface_get_height(surface);
@ -187,7 +185,7 @@ void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2, int rot, i
png_data[i + 1] = (unsigned char)(0xFF-png_g) + (unsigned char)((double)BG_g * ainv);
png_data[i + 2] = (unsigned char)(0xFF-png_b) + (unsigned char)((double)BG_b * ainv);
png_data[i + 3] = 0xFF;
}else
} else
{
png_data[i + 0] = png_r + (unsigned char)((double)BG_r * ainv);
png_data[i + 1] = png_g + (unsigned char)((double)BG_g * ainv);
@ -246,9 +244,6 @@ void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2, int rot, i
fprintf(fd, "3\n");
fprintf(fd, "colorimage\n");
fprintf(fd, "grestore\n");
#ifdef FFLUSH_PS /* FIXME: why is this needed? */
fflush(fd);
#endif
cairo_surface_destroy(surface);
my_free(1663, &hexEncodedJPG);
}
@ -359,9 +354,6 @@ void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
fprintf(fd, "3\n");
fprintf(fd, "colorimage\n");
fprintf(fd, "grestore\n");
#ifdef FFLUSH_PS /* FIXME: why is this needed? */
fflush(fd);
#endif
my_free(1666, &hexEncodedJPG);
#endif
@ -380,9 +372,6 @@ static void set_ps_colors(unsigned int pixel)
if(color_ps) fprintf(fd, "%g %g %g RGB\n",
(double)ps_colors[pixel].red/256.0, (double)ps_colors[pixel].green/256.0,
(double)ps_colors[pixel].blue/256.0);
#ifdef FFLUSH_PS /* FIXME: why is this needed? */
fflush(fd);
#endif
}

View File

@ -25,6 +25,35 @@
#include <sys/wait.h> /* waitpid */
#endif
/* splits a command string into argv-like arguments
* return # of args in *argc
* argv[*argc] is always set to NULL
* parse_cmd_string(NULL, NULL) to clear static allocated data */
#define PARSE_SIZE 128
char **parse_cmd_string(const char *cmd, int *argc)
{
static char *cmd_copy = NULL;
static char *argv[PARSE_SIZE];
char *cmd_ptr, *cmd_save;
if(!cmd || !cmd[0]) {
if(cmd_copy) my_free(1670, &cmd_copy);
return NULL;
}
*argc = 0;
my_strdup2(1669, &cmd_copy, cmd);
cmd_ptr = cmd_copy;
while( (argv[*argc] = my_strtok_r(cmd_ptr, " \t", "'\"", &cmd_save)) ) {
cmd_ptr = NULL;
dbg(1, "--> %s\n", argv[*argc]);
(*argc)++;
if(*argc >= PARSE_SIZE) break;
}
argv[*argc] = NULL; /*terminating pointer needed by execvp() */
return argv;
}
/* get an input databuffer (din[ilen]), and a shell command (cmd) that reads stdin
* and writes stdout, return the result in dout[olen].
* Caller must free the returned buffer.
@ -50,29 +79,32 @@ int filter_data(const char *din, const size_t ilen,
pipe(p1);
pipe(p2);
signal(SIGPIPE, SIG_IGN); /* so attempting write/read a broken pipe won't kill program */
/*
* p2
* ------------------- p2[0] <--------- p2[1] -------------------
* | Parent program | | Child filter |
* ------------------- p1[1] ---------> p1[0] -------------------
* p1
*/
if( (pid = fork()) == 0) {
char **av;
int ac;
/* child */
close(p1[1]); /* only read from p1 */
close(p2[0]); /* only write to p2 */
#if 0
dup2(p1[0],0); /* some systems lack this function */
#else
close(0); /* dup2(p1[0],0); */ /* connect read side of read pipe to stdin */
dup(p1[0]);
#endif
#if 0
dup2(p2[1],1); /* some systems lack this function */
#else
close(1); /* dup2(p2[1],1); */ /* connect write side of write pipe to stdout */
dup(p2[1]);
#endif
/* execlp("gm", "gm", "convert", "-", "-quality", "50", "jpg:-", NULL); */
if(system(cmd)) {
av = parse_cmd_string(cmd, &ac);
if(execvp(av[0], av) == -1) {
fprintf(stderr, "error: conversion failed\n");
close(p1[0]);
close(p2[1]);
ret = 1;
}
close(p1[0]);
close(p2[1]);
exit(ret);
}
/* parent */
@ -85,7 +117,7 @@ int filter_data(const char *din, const size_t ilen,
fsync(p1[1]);
close(p1[1]);
if(!ret) {
oalloc = bufsize + 1; /* add extra space for final '\0' */
oalloc = bufsize + 10000000; /* add extra space for final '\0' */
*dout = my_malloc(1480, oalloc);
*olen = 0;
while( (n = read(p2[0], *dout + *olen, bufsize)) > 0) {
@ -100,7 +132,6 @@ int filter_data(const char *din, const size_t ilen,
}
if(*olen) (*dout)[*olen] = '\0'; /* so (if ascii) it can be used as a string */
}
close(p2[0]);
if(n < 0 || !*olen) {
if(oalloc) {
my_free(1483, dout);
@ -110,6 +141,7 @@ int filter_data(const char *din, const size_t ilen,
ret = 1;
}
waitpid(pid, NULL, 0); /* write for child process to finish and unzombie it */
close(p2[0]);
signal(SIGPIPE, SIG_DFL); /* restore default SIGPIPE signal action */
return ret;
}

View File

@ -1875,7 +1875,19 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else { cmd_found = 0;}
break;
case 'p': /*----------------------------------------------*/
if(!strcmp(argv[1], "parselabel"))
if(!strcmp(argv[1], "parse_cmd"))
{
if(argc > 2) {
int c, i;
char **av;
av = parse_cmd_string(argv[2], &c);
for(i = 0; i < c; i++) {
dbg(0, "--> %s\n", av[i]);
}
}
}
else if(!strcmp(argv[1], "parselabel"))
{
if(argc > 2) {
parse(argv[2]);

View File

@ -1361,6 +1361,7 @@ extern void my_strndup(int id, char **dest, const char *src, size_t n);
extern size_t my_strdup2(int id, char **dest, const char *src);
extern char *my_fgets(FILE *fd);
extern char *my_strtok_r(char *str, const char *delim, const char *quote, char **saveptr);
extern char **parse_cmd_string(const char *cmd, int *argc);
extern int my_strncpy(char *d, const char *s, size_t n);
extern int my_strcasecmp(const char *s1, const char *s2);
extern double mylog10(double x);