]> git.ipfire.org Git - thirdparty/cups-filters.git/commitdiff
libcupsfilters: Let ghostscript() output Apple Raster directly
authorTill Kamppeter <till.kamppeter@gmail.com>
Mon, 11 Apr 2022 18:18:15 +0000 (20:18 +0200)
committerTill Kamppeter <till.kamppeter@gmail.com>
Mon, 11 Apr 2022 18:18:15 +0000 (20:18 +0200)
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
configure.ac
cupsfilters/filter.h
cupsfilters/ghostscript.c
cupsfilters/universal.c
mime/cupsfilters-ghostscript-appleraster.convs [new file with mode: 0644]

index 10e9161c52ce0d8a82ba846efb10a816ab4f8281..e8c2e535f5bf408362a474d200f8df6c5aba0324 100644 (file)
@@ -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)
 
index f05be23f5f936bbd3307bb97c1855c4c99c89299..40b846bb597c89260d578f5f0017595cce9a50cf 100644 (file)
@@ -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}
index baf3157b4e5b33ef87e6ed295583c1951fa6f587..e9bcd2f2f0da001bd1cfbe2cefa6224348418f15 100644 (file)
@@ -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,
index 6fa6d8f52c4980c497f7268ed3ef7d840b19e019..c6cddc159c06f0e5c13633cd4394a2463294ace0 100644 (file)
@@ -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 */
 
index 80513ae6934829e7c7a3859975217eea7390d3ec..a65f2f09fa5f6199ca5ed18a88110156d7c4d79f 100644 (file)
@@ -1,3 +1,4 @@
+#include "config.h"
 #include "filter.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -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 (file)
index 0000000..fde40a2
--- /dev/null
@@ -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