From 0bc9ec36a3650eda2b95d1a3476d21650d6ae12d Mon Sep 17 00:00:00 2001 From: Till Kamppeter Date: Mon, 11 Apr 2022 20:18:15 +0200 Subject: [PATCH] libcupsfilters: Let ghostscript() output Apple Raster directly From version 9.56.0 on Ghostscript support direct Apple Raster (URF) output. Therefore now we check via ./configure whether the installed Ghostscript has an "appleraster" output device and if so, we let the ghostscript() filter function call Ghostscript using this output device to directly output Apple Raster, so that we do not need to call the rastertopwg() filter function any more. In this case an extra MIME conversion rule taking into account the Apple Raster output from the gstoraster CUPS filter gets installed and also the universal() filter function gets built to not call the rastertopwg() filter function after ghostscript() when Apple Raster output is requested. --- Makefile.am | 6 +++ configure.ac | 28 ++++++++++--- cupsfilters/filter.h | 15 +++---- cupsfilters/ghostscript.c | 39 +++++++++++++------ cupsfilters/universal.c | 20 +++++----- .../cupsfilters-ghostscript-appleraster.convs | 18 +++++++++ 6 files changed, 93 insertions(+), 33 deletions(-) create mode 100644 mime/cupsfilters-ghostscript-appleraster.convs diff --git a/Makefile.am b/Makefile.am index 10e9161c5..e8c2e535f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -717,6 +717,8 @@ popplermimefiles = \ mime/cupsfilters-poppler.convs gsmimefiles = \ mime/cupsfilters-ghostscript.convs +gsapplerastermimefiles = \ + mime/cupsfilters-ghostscript-appleraster.convs mutoolmimefiles = \ mime/cupsfilters-mupdf.convs @@ -735,6 +737,9 @@ pkgmime_DATA += $(popplermimefiles) endif if ENABLE_GHOSTSCRIPT pkgmime_DATA += $(gsmimefiles) +if ENABLE_GHOSTSCRIPT_APPLERASTER +pkgmime_DATA += $(gsapplerastermimefiles) +endif endif if ENABLE_MUTOOL pkgmime_DATA += $(mutoolmimefiles) @@ -754,6 +759,7 @@ EXTRA_DIST += \ $(individualmimefiles) \ $(popplermimefiles) \ $(gsmimefiles) \ + $(gsapplerastermimefiles) \ $(mutoolmimefiles) \ $(brlmimefiles) diff --git a/configure.ac b/configure.ac index f05be23f5..40b846bb5 100644 --- a/configure.ac +++ b/configure.ac @@ -598,6 +598,11 @@ AC_ARG_ENABLE([gs-ps2write], [enable_gs_ps2write="$enableval"], [enable_gs_ps2write=yes] ) +AC_ARG_ENABLE([gs-appleraster], + [AS_HELP_STRING([--disable-gs-appleraster], [Ghostscript doesn't support appleraster device.])], + [enable_gs_appleraster="$enableval"], + [enable_gs_appleraster=yes] +) CUPS_GHOSTSCRIPT="" AS_IF([test "x$enable_ghostscript" != "xyes"], [ @@ -613,25 +618,36 @@ AS_IF([test "x$enable_ghostscript" != "xyes"], [ ]) ]) AS_IF([test "x$CUPS_GHOSTSCRIPT" = "x"], [ - AC_MSG_ERROR([Required gs binary is missing. Please install ghostscript-gpl package.]) + AC_MSG_ERROR([Required gs binary is missing. Please install ghostscript package.]) ]) AC_DEFINE([HAVE_GHOSTSCRIPT], [], [Define that we provide ghostscript binary]) AS_IF([test x"$with_pdftops" = xgs], [AC_DEFINE_UNQUOTED([CUPS_PDFTOPS_RENDERER], [GS], [Define default renderer])]) - AS_IF([test x"$enable_gs_ps2write" = "xyes"], [ - AC_DEFINE([HAVE_GHOSTSCRIPT_PS2WRITE], [], [gs supports ps2write]) - ]) AS_IF([test "x$cross_compiling" != "xyes"], [ AC_MSG_CHECKING(whether gs supports the ps2write device) AS_IF([`$CUPS_GHOSTSCRIPT -h 2>&1 | grep -q ps2write`], [ AC_MSG_RESULT([yes]) - AC_DEFINE([HAVE_GHOSTSCRIPT_PS2WRITE], [], [gs supports ps2write]) ], [ AC_MSG_RESULT([no]) + enable_gs_ps2write=no + ]) + AC_MSG_CHECKING(whether gs supports the appleraster device) + AS_IF([`$CUPS_GHOSTSCRIPT -h 2>&1 | grep -q appleraster`], [ + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + enable_gs_appleraster=no ]) ]) + AS_IF([test x"$enable_gs_ps2write" = "xyes"], [ + AC_DEFINE([HAVE_GHOSTSCRIPT_PS2WRITE], [], [gs supports ps2write]) + ]) + AS_IF([test x"$enable_gs_appleraster" = "xyes"], [ + AC_DEFINE([HAVE_GHOSTSCRIPT_APPLERASTER], [], [gs supports APPLERASTER]) + ]) ]) AM_CONDITIONAL(ENABLE_GHOSTSCRIPT, test "x$enable_ghostscript" = xyes) +AM_CONDITIONAL(ENABLE_GHOSTSCRIPT_APPLERASTER, test "x$enable_gs_appleraster" = xyes) AC_SUBST(CUPS_GHOSTSCRIPT) CUPS_MUTOOL="" @@ -970,6 +986,8 @@ Build configuration: poppler: ${enable_poppler} ghostscript: ${enable_ghostscript} gs-path: ${with_gs_path} + gs ps2write: ${enable_gs_ps2write} + gs appleraster: ${enable_gs_appleraster} mutool: ${enable_mutool} mutool-path: ${with_mutool_path} ippfind-path: ${with_ippfind_path} diff --git a/cupsfilters/filter.h b/cupsfilters/filter.h index baf3157b4..e9bcd2f2f 100644 --- a/cupsfilters/filter.h +++ b/cupsfilters/filter.h @@ -222,13 +222,14 @@ extern int cfFilterGhostscript(int inputfd, /* Parameters: cf_filter_out_format_t* Ouput format: PDF, raster-only PDF, PCLm, PostScript, CUPS Raster, PWG Raster, Apple Raster, PCL-XL - Note: On the Apple Raster selection the output is actually CUPS Raster - but information about available color spaces and depths is taken from - the urf-supported printer IPP attribute or appropriate PPD file - attribute. This mode is for further processing with rastertopwg. This can - change in the future when we add Apple Raster output support to - Ghostscript's "cups" output - device.*/ + Note: With the CF_FILTER_OUT_FORMAT_APPLE_RASTER selection and a + Ghostscript version without "appleraster" output device (9.55.x and + older) the output is actually CUPS Raster but information about + available color spaces and depths is taken from the urf-supported + printer IPP attribute or appropriate PPD file attribute. This mode + is for further processing with rastertopwg. With Ghostscript + supporting Apple Raster output (9.56.0 and newer), we actually + produce Apple Raster and no further filter is required. */ extern int cfFilterBannerToPDF(int inputfd, diff --git a/cupsfilters/ghostscript.c b/cupsfilters/ghostscript.c index 6fa6d8f52..c6cddc159 100644 --- a/cupsfilters/ghostscript.c +++ b/cupsfilters/ghostscript.c @@ -110,6 +110,9 @@ add_pdf_header_options(gs_page_header *h, cups_array_t *gs_args, if (outformat == CF_FILTER_OUT_FORMAT_CUPS_RASTER || outformat == CF_FILTER_OUT_FORMAT_PWG_RASTER || outformat == CF_FILTER_OUT_FORMAT_APPLE_RASTER) { +#ifdef HAVE_GHOSTSCRIPT_APPLERASTER + if (outformat != CF_FILTER_OUT_FORMAT_APPLE_RASTER) +#endif /* HAVE_GHOSTSCRIPT_APPLERASTER */ if (h->MediaClass[0] |= '\0') { snprintf(tmpstr, sizeof(tmpstr), "-sMediaClass=%s", h->MediaClass); cupsArrayAdd(gs_args, strdup(tmpstr)); @@ -719,13 +722,15 @@ cfFilterGhostscript(int inputfd, /* I - File descriptor input void *icd = data->iscanceleddata; - /* Note: With the CF_FILTER_OUT_FORMAT_APPLE_RASTER selection the output is - actually CUPS Raster but information about available color spaces - and depths is taken from the urf-supported printer IPP attribute - or appropriate PPD file attribute. This mode is for further - processing with rastertopwg. This can change in the future when - we add Apple Raster output support to Ghostscript's "cups" output - device. */ + /* Note: With the CF_FILTER_OUT_FORMAT_APPLE_RASTER selection and a + Ghostscript version without "appleraster" output device (9.55.x + and older) the output is actually CUPS Raster but information + about available color spaces and depths is taken from the + urf-supported printer IPP attribute or appropriate PPD file + attribute. This mode is for further processing with + rastertopwg. With Ghostscript supporting Apple Raster output + (9.56.0 and newer), we actually produce Apple Raster and no + further filter is required. */ if (parameters) { outformat = *(cf_filter_out_format_t *)parameters; @@ -1013,9 +1018,15 @@ cfFilterGhostscript(int inputfd, /* I - File descriptor input /* Ghostscript output device */ if (outformat == CF_FILTER_OUT_FORMAT_CUPS_RASTER || - outformat == CF_FILTER_OUT_FORMAT_PWG_RASTER || - outformat == CF_FILTER_OUT_FORMAT_APPLE_RASTER) +#ifndef HAVE_GHOSTSCRIPT_APPLERASTER + outformat == CF_FILTER_OUT_FORMAT_APPLE_RASTER || +#endif /* !HAVE_GHOSTSCRIPT_APPLERASTER */ + outformat == CF_FILTER_OUT_FORMAT_PWG_RASTER) cupsArrayAdd(gs_args, strdup("-sDEVICE=cups")); +#ifdef HAVE_GHOSTSCRIPT_APPLERASTER + else if (outformat == CF_FILTER_OUT_FORMAT_APPLE_RASTER) + cupsArrayAdd(gs_args, strdup("-sDEVICE=appleraster")); +#endif /* HAVE_GHOSTSCRIPT_APPLERASTER */ else if (outformat == CF_FILTER_OUT_FORMAT_PDF) cupsArrayAdd(gs_args, strdup("-sDEVICE=pdfwrite")); /* In case of PCL XL, raster-obly PDF, or PCLm output we determine @@ -1067,9 +1078,13 @@ cfFilterGhostscript(int inputfd, /* I - File descriptor input cspace = icc_profile ? CUPS_CSPACE_RGB : -1; cfRasterPrepareHeader(&h, data, outformat, - (outformat != CF_FILTER_OUT_FORMAT_APPLE_RASTER ? - outformat : CF_FILTER_OUT_FORMAT_CUPS_RASTER), 0, - &cspace); +#ifdef HAVE_GHOSTSCRIPT_APPLERASTER + outformat, +#else + (outformat != CF_FILTER_OUT_FORMAT_APPLE_RASTER ? + outformat : CF_FILTER_OUT_FORMAT_CUPS_RASTER), +#endif /* HAVE_GHOSTSCRIPT_APPLERASTER */ + 0, &cspace); /* Special Ghostscript options for raster-only PDF output */ diff --git a/cupsfilters/universal.c b/cupsfilters/universal.c index 80513ae69..a65f2f09f 100644 --- a/cupsfilters/universal.c +++ b/cupsfilters/universal.c @@ -1,3 +1,4 @@ +#include "config.h" #include "filter.h" #include #include @@ -320,9 +321,7 @@ cfFilterUniversal(int inputfd, /* I - File descriptor input stream */ *outformat = CF_FILTER_OUT_FORMAT_CUPS_RASTER; if (!strcmp(output_type, "pwg-raster")) *outformat = CF_FILTER_OUT_FORMAT_PWG_RASTER; - else if(!strcmp(output_type, "urf") || - (!strcmp(output_type, "vnd.cups-raster") && - !strcmp(final_output, "image/urf"))) + else if(!strcmp(output_type, "urf")) *outformat = CF_FILTER_OUT_FORMAT_APPLE_RASTER; else if(!strcmp(output_type, "PCLm")) *outformat = CF_FILTER_OUT_FORMAT_PCLM; @@ -334,6 +333,7 @@ cfFilterUniversal(int inputfd, /* I - File descriptor input stream */ if (log) log(ld, CF_LOGLEVEL_DEBUG, "cfFilterUniversal: Adding %s to chain", filter->name); +#ifndef HAVE_GHOSTSCRIPT_APPLERASTER if (!strcmp(output, "image/urf")) { filter = malloc(sizeof(cf_filter_filter_in_chain_t)); @@ -347,9 +347,11 @@ cfFilterUniversal(int inputfd, /* I - File descriptor input stream */ "cfFilterUniversal: Adding %s to chain", filter->name); } - else if (strcmp(output_type, "pwg-raster") && - strcmp(output_type, "vnd.cups-raster") && - strcmp(output_type, "PCLm")) + else +#endif /* !HAVE_GHOSTSCRIPT_APPLERASTER */ + if (strcmp(output_type, "pwg-raster") && + strcmp(output_type, "vnd.cups-raster") && + strcmp(output_type, "PCLm")) { outformat = malloc(sizeof(cf_filter_out_format_t)); *outformat = CF_FILTER_OUT_FORMAT_PDF; @@ -410,9 +412,7 @@ cfFilterUniversal(int inputfd, /* I - File descriptor input stream */ *outformat = CF_FILTER_OUT_FORMAT_CUPS_RASTER; if (!strcmp(output_type, "pwg-raster")) *outformat = CF_FILTER_OUT_FORMAT_PWG_RASTER; - else if (!strcmp(output_type, "urf") || - (!strcmp(output_type, "vnd.cups-raster") && - !strcmp(final_output, "image/urf"))) + else if (!strcmp(output_type, "urf")) *outformat = CF_FILTER_OUT_FORMAT_APPLE_RASTER; else if(!strcmp(output_type, "PCLm")) *outformat = CF_FILTER_OUT_FORMAT_PCLM; @@ -425,6 +425,7 @@ cfFilterUniversal(int inputfd, /* I - File descriptor input stream */ "cfFilterUniversal: Adding %s to chain", filter->name); +#ifndef HAVE_GHOSTSCRIPT_APPLERASTER if (!strcmp(output, "image/urf")) { filter = malloc(sizeof(cf_filter_filter_in_chain_t)); @@ -438,6 +439,7 @@ cfFilterUniversal(int inputfd, /* I - File descriptor input stream */ "cfFilterUniversal: Adding %s to chain", filter->name); } +#endif /* !HAVE_GHOSTSCRIPT_APPLERASTER */ } else if(!strcmp(output, "application/postscript") || !strcmp(output, "application/vnd.cups-postscript")) diff --git a/mime/cupsfilters-ghostscript-appleraster.convs b/mime/cupsfilters-ghostscript-appleraster.convs new file mode 100644 index 000000000..fde40a253 --- /dev/null +++ b/mime/cupsfilters-ghostscript-appleraster.convs @@ -0,0 +1,18 @@ +# +# MIME conversions file for OpenPrinting CUPS Filters. +# +# Copyright 2007-2011 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products. +# Copyright 2012-2016 by Till Kamppeter. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. and are protected by Federal copyright +# law. Distribution and use rights are outlined in the file "COPYING" +# which should have been included with this file. +# + +# +# Ghostscript-based filter for Apple Raster output... +# + +application/vnd.cups-pdf image/urf 99 gstoraster -- 2.47.3