From 1368e716097fc881afe7704715757cb5f92065f8 Mon Sep 17 00:00:00 2001 From: Till Kamppeter Date: Thu, 16 May 2019 12:24:06 +0200 Subject: [PATCH] pdftops, mupdftoraster: Let pdftops call mutool directly and so that it directly outputs PostScript. --- NEWS | 3 + filter/mupdftoraster.c | 21 +--- filter/pdftops.c | 240 ++++++++--------------------------------- 3 files changed, 52 insertions(+), 212 deletions(-) diff --git a/NEWS b/NEWS index 98efc540d..dcafe5046 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,9 @@ NEWS - OpenPrinting CUPS Filters v1.22.6 - 2019-05-15 CHANGES IN V1.23.0 + - pdftops, mupdftoraster: Let pdftops call mutool directly and + so that it directly outputs PostScript, eliminating the need + to call the mupdftoraster and rastertops filters. - mupdftoraster: Reduced the use of temporary files from 3 to just one. - imagetopdf, imagetoraster, pdftopdf: Add support for diff --git a/filter/mupdftoraster.c b/filter/mupdftoraster.c index 46317e147..8ba7a5743 100644 --- a/filter/mupdftoraster.c +++ b/filter/mupdftoraster.c @@ -118,8 +118,7 @@ parse_pdf_header_options(FILE *fp, mupdf_page_header *h) static void add_pdf_header_options(mupdf_page_header *h, - cups_array_t *mupdf_args, - int gray_output) + cups_array_t *mupdf_args) { char tmpstr[1024]; @@ -160,12 +159,6 @@ add_pdf_header_options(mupdf_page_header *h, snprintf(tmpstr, sizeof(tmpstr), "-cmono"); break; } - /* If we got called by pdftops, gray_output is set to 0 or 1, - 0 for a color job and 1 for a gray job */ - if (gray_output == 1) - snprintf(tmpstr, sizeof(tmpstr), "-cgray"); - else if (gray_output == 0) - snprintf(tmpstr, sizeof(tmpstr), "-ccmyk"); cupsArrayAdd(mupdf_args, strdup(tmpstr)); } @@ -253,7 +246,6 @@ main (int argc, char **argv, char *envp[]) int n; int num_options; int status = 1; - int gray_output = -1; ppd_file_t *ppd = NULL; struct sigaction sa; cm_calibration_t cm_calibrate; @@ -407,17 +399,8 @@ main (int argc, char **argv, char *envp[]) h.MirrorPrint = CUPS_FALSE; h.Orientation = CUPS_ORIENT_0; - /* If we got called by pdftops, the option "pdftops-mutool-gray" - is supplied and 0 for a color job and 1 for a gray job */ - t = cupsGetOption("pdftops-mutool-gray", num_options, options); - if (t) { - gray_output = atoi(t); - if (gray_output < 0 || gray_output > 1) - gray_output = -1; - } - /* get all the data from the header and pass it to mutool */ - add_pdf_header_options (&h, mupdf_args, gray_output); + add_pdf_header_options (&h, mupdf_args); snprintf(tmpstr, sizeof(tmpstr), "%s", infilename); cupsArrayAdd(mupdf_args, strdup(tmpstr)); diff --git a/filter/pdftops.c b/filter/pdftops.c index 791ceedf5..f50ba63da 100644 --- a/filter/pdftops.c +++ b/filter/pdftops.c @@ -106,17 +106,6 @@ const char *pstops_exclude_page_management[] = { }; -/* - * Options which we do not pass on to the mupdftoraster and rastertops - * filters when we render via MuPDF - */ - -const char *mupdf_exclude_general[] = { - "Resolution", - NULL -}; - - /* * Check whether we were called after the "pdftopdf" filter and extract * parameters passed over by "pdftopdf" in the header comments of the PDF @@ -297,9 +286,6 @@ main(int argc, /* I - Number of command-line args */ need_post_proc = 0, /* Post-processing needed? */ post_proc_pid = 0, /* Process ID of post-processing */ post_proc_pipe[2], /* Pipe to post-processing */ - need_rastertops = 0, /* rastertops (for MuPDF) needed */ - rastertops_pid = 0, /* Process ID of rastertops */ - rastertops_pipe[2], /* Pipe to rastertops */ wait_children, /* Number of child processes left */ wait_pid, /* Process ID from wait() */ wait_status, /* Status from child */ @@ -310,13 +296,6 @@ main(int argc, /* I - Number of command-line args */ *pstops_argv[7], /* Arguments for pstops filter */ *pstops_options, /* Options for pstops filter */ *pstops_end, /* End of pstops filter option */ - rastertops_path[1024], /* Path to rastertops program */ - *rastertops_argv[7], /* Arguments for rastertops filter */ - mupdftoraster_path[1024], /* Path to mupdftoraster program */ - *mupdf_options, /* Options for mupdftoraster and - rastertops filters */ - *mupdf_end, /* End of mupdftoraster and rastertops - filter option */ *ptr; /* Pointer into value */ const char *cups_serverbin; /* CUPS_SERVERBIN environment variable */ @@ -560,35 +539,6 @@ main(int argc, /* I - Number of command-line args */ log_command_line("pstops", pstops_argv); /* - * Build the rastertops command-line (MuPDF only)... - */ - - if (renderer == MUPDF) - { - if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL) - cups_serverbin = CUPS_SERVERBIN; - - snprintf(rastertops_path, sizeof(rastertops_path), "%s/filter/rastertops", - cups_serverbin); - - mupdf_options = strdup(argv[5]); - remove_options(mupdf_options, mupdf_exclude_general); - - rastertops_argv[0] = argv[0]; /* Printer */ - rastertops_argv[1] = argv[1]; /* Job */ - rastertops_argv[2] = argv[2]; /* User */ - rastertops_argv[3] = argv[3]; /* Title */ - if (pdftopdfapplied) - rastertops_argv[4] = deviceCopies; /* Copies */ - else - rastertops_argv[4] = argv[4]; /* Copies */ - rastertops_argv[5] = mupdf_options; /* Options */ - rastertops_argv[6] = NULL; - - log_command_line("rastertops", rastertops_argv); - } - - /* * Force monochrome/grayscale PostScript output * if job is to be printed in monochrome/grayscale */ @@ -625,7 +575,7 @@ main(int argc, /* I - Number of command-line args */ } /* - * Build the command-line for the pdftops, gs, pdftocairo, or + * Build the command-line for the pdftops, gs, mutool, pdftocairo, or * acroread filter... */ @@ -649,7 +599,8 @@ main(int argc, /* I - Number of command-line args */ # endif /* HAVE_GHOSTSCRIPT_PS2WRITE */ pdf_argv[7] = (char *)"-dShowAcroForm"; pdf_argv[8] = (char *)"-sOUTPUTFILE=%stdout"; - if (gray_output == 1) /* Checking for monochrome/grayscale PostScript output */ + if (gray_output == 1) /* Checking for monochrome/grayscale PostScript + output */ { pdf_argv[9] = (char *)"-sColorConversionStrategy=Gray"; pdf_argc = 10; @@ -657,6 +608,21 @@ main(int argc, /* I - Number of command-line args */ else pdf_argc = 9; } + else if (renderer == MUPDF) + { + pdf_argv[0] = (char *)"mutool"; + pdf_argv[1] = (char *)"draw"; + pdf_argv[2] = (char *)"-L"; + pdf_argv[3] = (char *)"-smtf"; + pdf_argv[4] = (char *)"-Fps"; + pdf_argv[5] = (char *)"-o-"; + if (gray_output == 1) /* Checking for monochrome/grayscale PostScript + output */ + pdf_argv[6] = (char *)"-cgray"; + else + pdf_argv[6] = (char *)"-crgb"; + pdf_argc = 7; + } else if (renderer == PDFTOCAIRO) { pdf_argv[0] = (char *)"pdftocairo"; @@ -669,23 +635,6 @@ main(int argc, /* I - Number of command-line args */ pdf_argv[1] = (char *)"-toPostScript"; pdf_argc = 2; } - else if (renderer == MUPDF) - { - snprintf(mupdftoraster_path, sizeof(mupdftoraster_path), - "%s/filter/mupdftoraster", cups_serverbin); - pdf_argv[0] = "mupdftoraster"; - pdf_argv[1] = argv[1]; /* Job */ - pdf_argv[2] = argv[2]; /* User */ - pdf_argv[3] = argv[3]; /* Title */ - if (pdftopdfapplied) - pdf_argv[4] = deviceCopies; /* Copies */ - else - pdf_argv[4] = argv[4]; /* Copies */ - pdf_argv[5] = mupdf_options; /* Options */ - pdf_argv[6] = filename; - pdf_argv[7] = NULL; - pdf_argc = 8; - } /* * Set language level and TrueType font handling... @@ -703,11 +652,11 @@ main(int argc, /* I - Number of command-line args */ else if (renderer == GS) pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=1"; else if (renderer == PDFTOCAIRO) - fprintf(stderr, "WARNING: Level 1 PostScript not supported by pdftocairo."); + fprintf(stderr, "WARNING: Level 1 PostScript not supported by pdftocairo.\n"); else if (renderer == ACROREAD) - fprintf(stderr, "WARNING: Level 1 PostScript not supported by acroread."); + fprintf(stderr, "WARNING: Level 1 PostScript not supported by acroread.\n"); else if (renderer == MUPDF) - fprintf(stderr, "WARNING: Level 1 PostScript not supported by rastertops."); + fprintf(stderr, "WARNING: Level 1 PostScript not supported by mutool.\n"); } else if (ppd->language_level == 2) { @@ -719,7 +668,8 @@ main(int argc, /* I - Number of command-line args */ } else if (renderer == GS) pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=2"; - else /* PDFTOCAIRO || ACROREAD */ + else if (renderer != MUPDF) /* MuPDF is PS level 2 only */ + /* PDFTOCAIRO, ACROREAD */ pdf_argv[pdf_argc++] = (char *)"-level2"; } else @@ -751,6 +701,8 @@ main(int argc, /* I - Number of command-line args */ else pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=3"; } + else if (renderer == MUPDF) + fprintf(stderr, "WARNING: Level 3 PostScript not supported by mutool.\n"); else /* PDFTOCAIRO || ACROREAD */ pdf_argv[pdf_argc++] = (char *)"-level3"; } @@ -773,7 +725,8 @@ main(int argc, /* I - Number of command-line args */ } else if (renderer == GS) pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=3"; - else /* PDFTOCAIRO || ACROREAD */ + else if (renderer != MUPDF) /* MuPDF is PS level 2 only */ + /* PDFTOCAIRO || ACROREAD */ pdf_argv[pdf_argc++] = (char *)"-level3"; } @@ -983,19 +936,13 @@ main(int argc, /* I - Number of command-line args */ /* * Add Resolution option to avoid slow processing by the printer when the * resolution of embedded images does not match the printer's resolution - * Also add pdftops-mutool-gray option to tell mupdftoraster whether the - * job is a to be printed in grayscale */ - mupdf_options = realloc(mupdf_options, strlen(mupdf_options) + 50); - if (!mupdf_options) { - fprintf(stderr, "ERROR: Can't allocate mupdf_options\n"); - exit(2); - } - mupdf_end = mupdf_options + strlen(mupdf_options); - snprintf(mupdf_end, 50, " Resolution=%ddpi pdftops-mutool-gray=%d", - res, gray_output); - pdf_argv[5] = mupdf_options; - rastertops_argv[5] = mupdf_options; + snprintf(resolution, 127, "-r%dx%d", res, res); + pdf_argv[pdf_argc++] = resolution; + /* + * Add input file name + */ + pdf_argv[pdf_argc++] = filename; } pdf_argv[pdf_argc] = NULL; @@ -1028,16 +975,7 @@ main(int argc, /* I - Number of command-line args */ need_post_proc = 1; /* - * Do we need to run rastertops when we are using mupdftoraster as PDF - * renderer - */ - - if (renderer == MUPDF) - need_rastertops = 1; - - /* - * Execute "pdftops/gs/mupdftoraster [ | rastertops ] [ | PS post-processing ] - * | pstops"... + * Execute "pdftops/gs/mutool [ | PS post-processing ] | pstops"... */ @@ -1054,17 +992,6 @@ main(int argc, /* I - Number of command-line args */ goto error; } - if (need_rastertops) - { - if (pipe(rastertops_pipe)) - { - perror("DEBUG: Unable to create pipe for rastertops"); - - exit_status = 1; - goto error; - } - } - if (need_post_proc) { if (pipe(post_proc_pipe)) @@ -1082,18 +1009,7 @@ main(int argc, /* I - Number of command-line args */ * Child comes here... */ - if (need_rastertops) - { - dup2(rastertops_pipe[1], 1); - close(rastertops_pipe[0]); - close(rastertops_pipe[1]); - if (need_post_proc) - { - close(post_proc_pipe[0]); - close(post_proc_pipe[1]); - } - } - else if (need_post_proc) + if (need_post_proc) { dup2(post_proc_pipe[1], 1); close(post_proc_pipe[0]); @@ -1136,8 +1052,8 @@ main(int argc, /* I - Number of command-line args */ } else if (renderer == MUPDF) { - execvp(mupdftoraster_path, pdf_argv); - perror("DEBUG: Unable to execute mupdftoraster program"); + execvp(CUPS_MUTOOL, pdf_argv); + perror("DEBUG: Unable to execute mutool program"); } exit(1); @@ -1157,7 +1073,7 @@ main(int argc, /* I - Number of command-line args */ else if (renderer == ACROREAD) perror("DEBUG: Unable to execute acroread program"); else if (renderer == MUPDF) - perror("DEBUG: Unable to execute mupdftoraster program"); + perror("DEBUG: Unable to execute mutool program"); exit_status = 1; goto error; @@ -1165,47 +1081,6 @@ main(int argc, /* I - Number of command-line args */ fprintf(stderr, "DEBUG: Started filter %s (PID %d)\n", pdf_argv[0], pdf_pid); - if (need_rastertops) - { - if ((rastertops_pid = fork()) == 0) - { - /* - * Child comes here... - */ - - dup2(rastertops_pipe[0], 0); - close(rastertops_pipe[0]); - close(rastertops_pipe[1]); - if (need_post_proc) - { - dup2(post_proc_pipe[1], 1); - close(post_proc_pipe[0]); - close(post_proc_pipe[1]); - } - else - dup2(pstops_pipe[1], 1); - close(pstops_pipe[0]); - close(pstops_pipe[1]); - - execvp(rastertops_path, rastertops_argv); - perror("DEBUG: Unable to execute rastertops program"); - } - else if (post_proc_pid < 0) - { - /* - * Unable to fork! - */ - - perror("DEBUG: Unable to execute rastertops program"); - - exit_status = 1; - goto error; - } - - fprintf(stderr, "DEBUG: Started filter rastertops (PID %d)\n", - rastertops_pid); - } - if (need_post_proc) { if ((post_proc_pid = fork()) == 0) @@ -1220,11 +1095,6 @@ main(int argc, /* I - Number of command-line args */ dup2(pstops_pipe[1], 1); close(pstops_pipe[0]); close(pstops_pipe[1]); - if (need_rastertops) - { - close(rastertops_pipe[0]); - close(rastertops_pipe[1]); - } fp = cupsFileStdin(); @@ -1551,11 +1421,6 @@ main(int argc, /* I - Number of command-line args */ dup2(pstops_pipe[0], 0); close(pstops_pipe[0]); close(pstops_pipe[1]); - if (need_rastertops) - { - close(rastertops_pipe[0]); - close(rastertops_pipe[1]); - } if (need_post_proc) { close(post_proc_pipe[0]); @@ -1588,17 +1453,12 @@ main(int argc, /* I - Number of command-line args */ close(post_proc_pipe[0]); close(post_proc_pipe[1]); } - if (need_rastertops) - { - close(rastertops_pipe[0]); - close(rastertops_pipe[1]); - } /* * Wait for the child processes to exit... */ - wait_children = 2 + need_rastertops + need_post_proc; + wait_children = 2 + need_post_proc; while (wait_children > 0) { @@ -1611,8 +1471,6 @@ main(int argc, /* I - Number of command-line args */ if (job_canceled) { kill(pdf_pid, SIGTERM); - if (need_rastertops) - kill(rastertops_pid, SIGTERM); if (need_post_proc) kill(post_proc_pid, SIGTERM); kill(pstops_pid, SIGTERM); @@ -1643,12 +1501,11 @@ main(int argc, /* I - Number of command-line args */ (renderer == PDFTOCAIRO ? "pdftocairo" : (renderer == GS ? "gs" : (renderer == ACROREAD ? "acroread" : - (renderer == MUPDF ? "mupdftoraster" : + (renderer == MUPDF ? "mutool" : "Unknown renderer"))))) : (wait_pid == pstops_pid ? "pstops" : - (wait_pid == rastertops_pid ? "rastertops" : (wait_pid == post_proc_pid ? "Post-processing" : - "Unknown process"))), + "Unknown process")), exit_status); } else if (WTERMSIG(wait_status) == SIGTERM) @@ -1661,12 +1518,11 @@ main(int argc, /* I - Number of command-line args */ (renderer == PDFTOCAIRO ? "pdftocairo" : (renderer == GS ? "gs" : (renderer == ACROREAD ? "acroread" : - (renderer == MUPDF ? "mupdftoraster" : + (renderer == MUPDF ? "mutool" : "Unknown renderer"))))) : (wait_pid == pstops_pid ? "pstops" : - (wait_pid == rastertops_pid ? "rastertops" : (wait_pid == post_proc_pid ? "Post-processing" : - "Unknown process"))), + "Unknown process")), exit_status); } else @@ -1680,12 +1536,11 @@ main(int argc, /* I - Number of command-line args */ (renderer == PDFTOCAIRO ? "pdftocairo" : (renderer == GS ? "gs" : (renderer == ACROREAD ? "acroread" : - (renderer == MUPDF ? "mupdftoraster" : + (renderer == MUPDF ? "mutool" : "Unknown renderer"))))) : (wait_pid == pstops_pid ? "pstops" : - (wait_pid == rastertops_pid ? "rastertops" : (wait_pid == post_proc_pid ? "Post-processing" : - "Unknown process"))), + "Unknown process")), exit_status); } } @@ -1698,12 +1553,11 @@ main(int argc, /* I - Number of command-line args */ (renderer == PDFTOCAIRO ? "pdftocairo" : (renderer == GS ? "gs" : (renderer == ACROREAD ? "acroread" : - (renderer == MUPDF ? "mupdftoraster" : + (renderer == MUPDF ? "mutool" : "Unknown renderer"))))) : (wait_pid == pstops_pid ? "pstops" : - (wait_pid == rastertops_pid ? "rastertops" : (wait_pid == post_proc_pid ? "Post-processing" : - "Unknown process")))); + "Unknown process"))); } }