The core of the CUPS filtering system is based on Ghostscript. In addition to Ghostscript, CUPS uses some other filters of its own. You (or your OS vendor) may have plugged in even more filters. CUPS handles all data file formats under the label of various MIME types. Every incoming printfile is subjected to an initial auto-typing. The auto-typing determines its given MIME type. A given MIME type implies zero or more possible filtering chains relevant to the selected target printer. This section discusses how MIME types recognition and conversion rules interact. They are used by CUPS to automatically setup a working filtering chain for any given input data format.
If CUPS rasterizes a PostScript file natively to a bitmap, this is done in two stages:
Make sure your Ghostscript version has the " cups " device compiled in (check with gs -h grep cups ). Otherwise you may encounter the dreaded Unable to convert file 0 in your CUPS error_log file. To have " cups " as a device in your Ghostscript, you either need to patch GNU Ghostscript and re-compile, or use ESP Ghostscript  . The superior alternative is ESP Ghostscript. It supports not just CUPS, but 300 other devices too (while GNU Ghostscript supports only about 180). Because of this broad output device support, ESP Ghostscript is the first choice for non-CUPS spoolers, too. It is now recommended by Linuxprinting.org for all spoolers.
CUPS printers may be setup to use external rendering paths. One of the most common is provided by the Foomatic/cupsomatic concept from Linuxprinting.org.  This uses the classical Ghostscript approach, doing everything in one step. It does not use the " cups " device, but one of the many others. However, even for Foomatic/cupsomatic usage, best results and broadest printer model support is provided by ESP Ghostscript (more about cupsomatic/Foomatic, particularly the new version called now foomatic-rip , follows below).
18.5.1 MIME Types and CUPS Filters
CUPS reads the file /etc/cups/mime.types (and all other files carrying a *.types suffix in the same directory) upon startup. These files contain the MIME type recognition rules that are applied when CUPS runs its auto-typing routines. The rule syntax is explained in the man page for mime.types and in the comments section of the mime.types file itself. A simple rule reads like this:
application/pdf pdf string(0,%PDF)
This means if a filename has either a .pdf suffix or if the magic string %PDF is right at the beginning of the file itself (offset 0 from the start), then it is a PDF file ( application/pdf ). Another rule is this:
application/postscript ai eps ps string(0,%!) string(0,<04>%!)
If the filename has one of the suffixes .ai , .eps , .ps or if the file itself starts with one of the strings %! or < 04>%! , it is a generic PostScript file ( application/postscript ).
CUPS can handle ASCII text, HP-GL, PDF, PostScript, DVI, and many image formats (GIF. PNG, TIFF, JPEG, Photo-CD, SUN-Raster, PNM, PBM, SGI-RGB, and more) and their associated MIME types with its filters.
18.5.2 MIME Type Conversion Rules
CUPS reads the file /etc/cups/mime.convs (and all other files named with a *.convs suffix in the same directory) upon startup. These files contain lines naming an input MIME type, an output MIME type, a format conversion filter that can produce the output from the input type and virtual costs associated with this conversion. One example line reads like this:
application/pdf application/postscript 33 pdftops
This means that the pdftops filter will take application/pdf as input and produce application/postscript as output; the virtual cost of this operation is 33 CUPS-$. The next filter is more expensive, costing 66 CUPS-$:
application/vnd.hp-HPGL application/postscript 66 hpgltops
This is the hpgltops , which processes HP-GL plotter files to PostScript.
Here are two more examples:
application/x-shell application/postscript 33 texttops text/plain application/postscript 33 texttops
The last two examples name the texttops filter to work on text/plain as well as on application/x-shell . (Hint: This differentiation is needed for the syntax highlighting feature of texttops ).
18.5.3 Filtering Overview
There are many more combinations named in mime.convs . However, you are not limited to use the ones pre-defined there. You can plug in any filter you like into the CUPS framework. It must meet, or must be made to meet, some minimal requirements. If you find (or write) a cool conversion filter of some kind, make sure it complies to what CUPS needs and put in the right lines in mime.types and mime.convs , then it will work seamlessly inside CUPS.
188.8.131.52 Filter requirements
The mentioned " CUPS requirements " for filters are simple. Take filenames or stdin as input and write to stdout . They should take these 5 or 6 arguments: printer job user title copies options [filename]
Printer ” The name of the printer queue (normally this is the name of the filter being run).
job ” The numeric job ID for the job being printed.
user ” The string from the originating-user-name attribute.
title ” The string from the job-name attribute.
copies ” The numeric value from the number-copies attribute.
options ” The job options.
filename ” (Optionally) The print request file (if missing, filters expected data fed through stdin ). In most cases, it is easy to write a simple wrapper script around existing filters to make them work with CUPS.
As previously stated, PostScript is the central file format to any UNIX-based printing system. From PostScript, CUPS generates raster data to feed non-PostScript printers.
But what happens if you send one of the supported non-PS formats to print? Then CUPS runs " pre-filters " on these input formats to generate PostScript first. There are pre-filters to create PS from ASCII text, PDF, DVI, or HP-GL. The outcome of these filters is always of MIME type application/postscript (meaning that any device-specific print options are not yet embedded into the PostScript by CUPS, and that the next filter to be called is pstops). Another pre-filter is running on all supported image formats, the imagetops filter. Its outcome is always of MIME type application/vnd.cups-postscript (not application/postscript), meaning it has the print options already embedded into the file.
Figure 18.4. Pre-filtering in CUPS to form PostScript.
pstops is the filter to convert application/postscript to application/vnd.cups-postscript . It was said above that this filter inserts all device-specific print options (commands to the printer to ask for the duplexing of output, or stapling and punching it, and so on) into the PostScript file.
Figure 18.5. Adding device-specific print options.
This is not all. Other tasks performed by it are:
pstoraster is at the core of the CUPS filtering system. It is responsible for the first stage of the rasterization process. Its input is of MIME type application/vnd.cups-postscript; its output is application/vnd.cups-raster. This output format is not yet meant to be printable. Its aim is to serve as a general purpose input format for more specialized raster drivers that are able to generate device-specific printer data.
Figure 18.6. PostScript to intermediate raster format.
CUPS raster is a generic raster format with powerful features. It is able to include per-page information, color profiles, and more, to be used by the following downstream raster drivers. Its MIME type is registered with IANA and its specification is, of course, completely open . It is designed to make it quite easy and inexpensive for manufacturers to develop Linux and UNIX raster drivers for their printer models, should they choose to do so. CUPS always takes care for the first stage of rasterization so these vendors do not need to care about Ghostscript complications (in fact, there is currently more than one vendor financing the development of CUPS raster drivers).
CUPS versions before version 1.1.15 were shipping a binary (or source code) standalone filter, named pstoraster. pstoraster was derived from GNU Ghostscript 5.50, and could be installed besides and in addition to any GNU or AFPL Ghostscript package without conflicting.
>From version 1.1.15, this has changed. The functions for this have been integrated back into Ghostscript (now based on GNU Ghostscript version 7.05). The pstoraster filter is now a simple shell script calling gs with the -sDEVICE=cups parameter. If your Ghostscript does not show a success on asking for gs -h grep cups , you might not be able to print. Update your Ghostscript.
18.5.7 imagetops and imagetoraster
In the section about pre-filters, we mentioned the pre-filter that generates PostScript from image formats. The imagetoraster filter is used to convert directly from image to raster, without the intermediate PostScript stage. It is used more often than the above mentioned pre-filters. A summarizing flowchart of image file filtering is shown in Figure 18.8.
Figure 18.7. CUPS-raster production using Ghostscript.
Figure 18.8. Image format to CUPS-raster format conversion.
18.5.8 rasterto [printers specific]
CUPS ships with quite different raster drivers processing CUPS raster. On my system I find in /usr/lib/cups/filter/ these: rastertoalps , rastertobj , rastertoepson , rastertoescp , rastertopcl , rastertoturboprint , rastertoapdk , rastertodymo , rastertoescp , rastertohp , and rastertoprinter . Don't worry if you have less than this; some of these are installed by commercial add-ons to CUPS (like rastertoturboprint ), others (like rastertoprinter ) by third-party driver development projects (such as Gimp-Print) wanting to cooperate as closely as possible with CUPS.
18.5.9 CUPS Backends
The last part of any CUPS filtering chain is a backend. Backends are special programs that send the print-ready file to the final device. There is a separate backend program for any transfer protocol of sending printjobs over the network, or for every local interface. Every CUPS print queue needs to have a CUPS " device-URI " associated with it. The device URI is the way to encode the backend used to send the job to its destination. Network device-URIs are using two slashes in their syntax, local device URIs only one, as you can see from the following list. Keep in mind that local interface names may vary much from my examples, if your OS is not Linux:
usb ” This backend sends printfiles to USB-connected printers. An example for the CUPS device-URI to use is: usb:/dev/usb/lp0 .
serial ” This backend sends printfiles to serially connected printers. An example for the CUPS device-URI to use is: serial:/dev/ttyS0?baud=11500 .
parallel ” This backend sends printfiles to printers connected to the parallel port. An example for the CUPS device-URI to use is: parallel:/dev/lp0 .
scsi ” This backend sends printfiles to printers attached to the SCSI interface. An example for the CUPS device-URI to use is: scsi:/dev/sr1 .
lpd ” This backend sends printfiles to LPR/LPD connected network printers. An example for the CUPS device-URI to use is: lpd://remote_host_name/remote_queue_name .
AppSocket/HP JetDirect ” This backend sends printfiles to AppSocket (a.k.a. "HP JetDirect") connected network printers. An example for the CUPS device-URI to use is: socket://10.11.12.13:9100 .
ipp ” This backend sends printfiles to IPP connected network printers (or to other CUPS servers). Examples for CUPS device-URIs to use are: ipp:://184.108.40.206/ipp (for many HP printers) or ipp://remote_cups_server/printers/remote_printer_name .
Figure 18.9. Raster to printer-specific formats.
http ” This backend sends printfiles to HTTP connected printers. (The http:// CUPS backend is only a symlink to the ipp://backend.) Examples for the CUPS device-URIs to use are: http:://220.127.116.11:631/ipp (for many HP printers) or http://remote_cups_server:631/printers/remote_printer_name .
smb ” This backend sends printfiles to printers shared by a Windows host. An example for CUPS device-URIs that may be used includes:
smb://workgroup/server/printersharename smb://server/printersharename smb://username:password@workgroup/server/printersharename smb://username:password@server/printersharename
The smb:// backend is a symlink to the Samba utility smbspool (does not ship with CUPS). If the symlink is not present in your CUPS backend directory, have your root user create it: ln -s 'which smbspool' /usr/lib/cups/backend/smb .
It is easy to write your own backends as shell or Perl scripts, if you need any modification or extension to the CUPS print system. One reason could be that you want to create " special " printers that send the printjobs as email (through a " mailto :/" backend), convert them to PDF (through a " pdfgen: /" backend) or dump them to " /dev/null ". (In fact I have the system-wide default printer set up to be connected to a devnull:/ backend: there are just too many people sending jobs without specifying a printer, or scripts and programs which do not name a printer. The system-wide default deletes the job and sends a polite email back to the $USER asking him to always specify the correct printer name.)
Not all of the mentioned backends may be present on your system or usable (depending on your hardware configuration). One test for all available CUPS backends is provided by the lpinfo utility. Used with the -v parameter, it lists all available backends:
$ lpinfo -v
18.5.10 The Role of cupsomatic/foomatic
cupsomatic filters may be the most widely used on CUPS installation. You must be clear about the fact that these were not developed by the CUPS people. They are a third party add-on to CUPS. They utilize the traditional Ghostscript devices to render jobs for CUPS. When troubleshooting, you should know about the difference. Here the whole rendering process is done in one stage, inside Ghostscript, using an appropriate device for the target printer. cupsomatic uses PPDs that are generated from the Foomatic Printer & Driver Database at Linuxprinting.org.
You can recognize these PPDs from the line calling the cupsomatic filter:
*cupsFilter: "application/vnd.cups-postscript 0 cupsomatic"
You may find this line among the first 40 or so lines of the PPD file. If you have such a PPD installed, the printer shows up in the CUPS Web interface with a foomatic namepart for the driver description. cupsomatic is a Perl script that runs Ghostscript with all the complicated command line options auto- constructed from the selected PPD and command line options give to the printjob .
However, cupsomatic is now deprecated. Its PPDs ( especially the first generation of them, still in heavy use out there) are not meeting the Adobe specifications. You might also suffer difficulties when you try to download them with " Point'n'Print " to Windows clients . A better and more powerful successor is now in a stable beta-version: it is called foomatic-rip . To use foomatic-rip as a filter with CUPS, you need the new-type PPDs. These have a similar but different line:
*cupsFilter: "application/vnd.cups-postscript 0 foomatic-rip"
The PPD generating engine at Linuxprinting.org has been revamped . The new PPDs comply to the Adobe spec. On top, they also provide a new way to specify different quality levels (hi-res photo, normal color, grayscale, and draft) with a single click, whereas before you could have required five or more different selections (media type, resolution, inktype and dithering algorithm). There is support for custom-size media built in. There is support to switch print-options from page to page in the middle of a job. And the best thing is the new foomatic-rip now works seamlessly with all legacy spoolers too (like LPRng, BSD-LPD, PDQ, PPR and so on), providing for them access to use PPDs for their printing.
18.5.11 The Complete Picture
If you want to see an overview of all the filters and how they relate to each other, the complete picture of the puzzle is at the end of this document.
CUPS auto-constructs all possible filtering chain paths for any given MIME type, and every printer installed. But how does it decide in favor or against a specific alternative? (There may often be cases where there is a choice of two or more possible filtering chains for the same target printer.) Simple. You may have noticed the figures in the third column of the mime.convs file. They represent virtual costs assigned to this filter. Every possible filtering chain will sum up to a total " filter cost ." CUPS decides for the most " inexpensive " route.
18.5.13 " Raw " Printing
You can tell CUPS to print (nearly) any file " raw ". " Raw " means it will not be filtered. CUPS will send the file to the printer " as is " without bothering if the printer is able to digest it. Users need to take care themselves that they send sensible data formats only. Raw printing can happen on any queue if the " -o raw " option is specified on the command line. You can also set up raw-only queues by simply not associating any PPD with it. This command:
$ lpadmin -P rawprinter -v socket://18.104.22.168:9100 -E
sets up a queue named " rawprinter ", connected via the " socket " protocol (a.k.a. " HP JetDirect ") to the device at IP address 22.214.171.124.14, using port 9100. (If you had added a PPD with -P / path /to/PPD to this command line, you would have installed a " normal " print queue.
CUPS will automatically treat each job sent to a queue as a " raw " one, if it can't find a PPD associated with the queue. However, CUPS will only send known MIME types (as defined in its own mime.types file) and refuse others.
18.5.14 application/octet-stream Printing
Any MIME type with no rule in the /etc/cups/mime.types file is regarded as unknown or application/octet-stream and will not be sent. Because CUPS refuses to print unknown MIME types per default, you will probably have experienced the fact that print jobs originating from Windows clients were not printed. You may have found an error message in your CUPS logs like:
Unable to convert file 0 to printable format for job
To enable the printing of application/octet-stream files, edit these two files:
Both contain entries (at the end of the respective files) which must be uncommented to allow RAW mode operation for application/octet-stream . In /etc/cups/mime.types make sure this line is present:
This line (with no specific auto-typing rule set) makes all files not otherwise auto-typed a member of application/octet-stream . In /etc/cups/mime.convs , have this line:
application/octet-stream application/vnd.cups-raw 0 -
This line tells CUPS to use the Null Filter (denoted as "-", doing nothing at all) on application/octet-stream , and tag the result as application/vnd.cups-raw . This last one is always a green light to the CUPS scheduler to now hand the file over to the backend connecting to the printer and sending it over.
CUPS being a more security-aware printing system than traditional ones does not by default allow one to send deliberate (possibly binary) data to printing devices. (This could be easily abused to launch a Denial of Service attack on your printer(s), causing at least the loss of a lot of paper and ink...) " Unknown " data are regarded by CUPS as MIME type application/octet-stream . While you can send data " raw ", the MIME type for these must be one that is known to CUPS and an allowed one. The file /etc/cups/mime.types defines the " rules " of how CUPS recognizes MIME types. The file /etc/cups/mime.convs decides which file conversion filter(s) may be applied to which MIME types.
18.5.15 PostScript Printer Descriptions (PPDs) for Non-PS Printers
Originally PPDs were meant to be used for PostScript printers only. Here, they help to send device-specific commands and settings to the RIP which processes the jobfile. CUPS has extended this scope for PPDs to cover non-PostScript printers too. This was not difficult, because it is a standardized file format. In a way it was logical too: CUPS handles PostScript and uses a PostScript RIP (Ghostscript) to process the jobfiles. The only difference is: a PostScript printer has the RIP built-in, for other types of printers the Ghostscript RIP runs on the host computer.
PPDs for a non-PS printer have a few lines that are unique to CUPS. The most important one looks similar to this:
*cupsFilter: application/vnd.cups-raster 66 rastertoprinter
It is the last piece in the CUPS filtering puzzle. This line tells the CUPS daemon to use as a last filter rastertoprinter . This filter should be served as input an application/vnd.cups-raster MIME type file. Therefore, CUPS should auto-construct a filtering chain, which delivers as its last output the specified MIME type. This is then taken as input to the specified rastertoprinter filter. After this the last filter has done its work ( rastertoprinter is a Gimp-Print filter), the file should go to the backend, which sends it to the output device.
CUPS by default ships only a few generic PPDs, but they are good for several hundred printer models. You may not be able to control different paper trays, or you may get larger margins than your specific model supports. See Table 18.1 for summary information.
Table 18.1. PPDs shipped with CUPS
18.5.16 cupsomatic/foomatic-rip Versus native CUPS Printing
Native CUPS rasterization works in two steps:
Often this produces better quality (and has several more advantages) than other methods .
One other method is the cupsomatic/foomatic-rip way. Note that cupsomatic is not made by the CUPS developers. It is an independent contribution to printing development, made by people from Linuxprinting.org  . cupsomatic is no longer developed and maintained and is no longer supported. It has now been replaced by foomatic-rip . foomatic-rip is a complete re-write of the old cupsomatic idea, but very much improved and generalized to other (non-CUPS) spoolers. An upgrade to foomatic-rip is strongly advised, especially if you are upgrading to a recent version of CUPS, too.
Both the cupsomatic (old) and the foomatic-rip (new) methods from Linuxprinting.org use the traditional Ghostscript print file processing, doing everything in a single step. It therefore relies on all the other devices built into Ghostscript. The quality is as good (or bad) as Ghostscript rendering is in other spoolers. The advantage is that this method supports many printer models not supported (yet) by the more modern CUPS method.
Of course, you can use both methods side by side on one system (and even for one printer, if you set up different queues) and find out which works best for you.
cupsomatic kidnaps the printfile after the application/vnd.cups-postscript stage and deviates it through the CUPS-external, system-wide Ghostscript installation. Therefore the printfile bypasses the pstoraster filter (and also bypasses the CUPS-raster-drivers rastertosomething ). After Ghostscript finished its rasterization, cupsomatic hands the rendered file directly to the CUPS backend. The flowchart in Figure 18.10 illustrates the difference between native CUPS rendering and the Foomatic/cupsomatic method.
Figure 18.10. cupsomatic/foomatic Processing versus Native CUPS.
18.5.17 Examples for Filtering Chains
Here are a few examples of commonly occurring filtering chains to illustrate the workings of CUPS.
Assume you want to print a PDF file to an HP JetDirect-connected PostScript printer, but you want to print the pages 3-5, 7, 11-13 only, and you want to print them " two-up " and " duplex ":
The resulting filter chain, therefore, is as drawn in Figure 18.11.
Figure 18.11. PDF to socket chain.
Assume your want to print the same filter to an USB-connected Epson Stylus Photo printer installed with the CUPS stphoto2.ppd . The first few filtering stages are nearly the same:
The resulting filter chain therefore is as drawn in Figure 18.12.
Figure 18.12. PDF to USB chain.
18.5.18 Sources of CUPS Drivers/PPDs
On the Internet you can now find many thousands of CUPS-PPD files (with their companion filters), in many national languages supporting more than thousand non-PostScript models.
18.5.19 Printing with Interface Scripts
CUPS also supports the usage of " interface scripts " as known from System V AT&T printing systems. These are often used for PCL printers, from applications that generate PCL print jobs. Interface scripts are specific to printer models. They have a similar role as PPDs for PostScript printers. Interface scripts may inject the Escape sequences as required into the print data stream, if the user has chosen to select a certain paper tray, or print landscape, or use A3 paper, etc. Interfaces scripts are practically unknown in the Linux realm. On HP-UX platforms they are more often used. You can use any working interface script on CUPS too. Just install the printer with the -i option:
root# lpadmin -p pclprinter -v socket://126.96.36.199:9100 \ -i /path/to/interface-script
Interface scripts might be the " unknown animal " to many. However, with CUPS they provide the easiest way to plug in your own custom-written filtering script or program into one specific print queue (some information about the traditional usage of interface scripts is to be found at http://playground.sun.com/printing/documentation/interface.html).