Translation(s): none


cupsfilter uses the CUPS printing system filters to convert a file to another format.

Introduction

cupsfilter is provided by the cups package. The idea behind it is to use the filter subsystem (provided on Jessie in the cups, cups-server, cups-daemon, cups-filters and cups-filters-core-drivers packages) to convert a file to a specific format. The processing is identical to that done by CUPS and the filter subsystem when a file makes its way to the printer and ink or toner is put on paper; except there is no paper output.

We can use cupsfilter to examine the state of the filter conversions at each stage of the filtering process and determine whether behaviour is reasonable and correct. The filters in /usr/lib/cups/filter can also be used as standalone programs to examine the conversions but this is not generally encouraged. Please see filter(7).

File Viewers

The ease of examining the output from cupsfilter depends on the file type. PDF and PostScript can easily be viewed by gv, xpdf, mupdf, Evince, Okular etc. etc. Raster output viewing is a little harder to accomplish because there is no Debian package for the viewer. One, RasterView, may be downloaded from http://www.msweet.org/index.php. The executable can be compiled from source after installing the g++ and libfltk1.3-dev packages and doing ./configure plus make. The rasterview executable produced would be put in /usr/local/bin. Alternatively, the RPM package can be converted to a Debian package with alien and installed with dpkg -i.

Using RasterView isn't too hard. Zooming in and out is mouse-driven; or the - and = keys can be used. The bottom left of the window has a button |>| for moving on a page. From the keyboard SHIFT+SPACE does the same job. The ESC key exits the program.

Viewing the file which is actually sent to the printer (the printer-ready file) may or may not be possible because it depends on whether it is PostScript, PDF, PCL or just data (which is often in a proprietry format). A PCL viewer is at http://www.ghostscript.com/download/gpcldnld.html. It is sufficient to put the pcl6-916-linux_x86 binary in /usr/local/bin for it to function. The only way to "view" a file which is classified by the file program as data is to send it to the printer without passing through the filtering system. One way is:

   lp -d <print_queue> -o raw <final_file>

cupsfilter is in Wheezy and Jessie but the use examples described here use the Jessie version and its documentation. The version which comes with cups 2.0.2-2 has acquired a useful --list-filters option. If extracted from that cups package and used to replace the Jessie version you should find it works without detracting from any of the existing functionality.

Using a PPD File with Cupsfilter

You almost certainly want to use a PPD file with cupsfilter. As root on Jessie you will have access to one in /etc/cups/ppd; as a user you will not. If you want to test the filtering of an installed print queue as a user you can get its PPD file using cups-driverd.

Let's suppose the print queue is for a LaserJet 2200 using the Gutenprint PPD. A searchable list of PPDs on the system is available to a user with

  /usr/sbin/lpinfo -m | less

and we find the URI for the PPD is

  gutenprint.5.2://hp-lj_2200/expert

Then

  /usr/lib/cups/daemon/cups-driverd cat gutenprint.5.2://hp-lj_2200/expert > laserjet2200.ppd

gives you the PPD.

Specifying the Destination File Type

You will almost certainly want to use the -m option to cupsfilter. application/pdf and application/postscript are possibilities (the first is the default) but it is more likely application/vnd.cups-pdf, application/vnd.cups-postscript and application/vnd.cups-raster are wanted at some point.

application/vnd.cups-* indicates a printer-ready file. There are print options which the printer may not be able to handle by itself; for example N-up, scaling and rotation . These are applied to the pages in the file by a filter, usually pdftopdf.

There is a PostScript file, test.ps, attached to this page. Download it or use one of your own. Now for the first test; as a user:

  /usr/sbin/cupsfilter -p laserjet2200.ppd -m application/postscript -o number-up=2 test.ps > out.ps 2> log

You should find out.ps looks no different from test.ps. In fact, it is also the same size as test.ps. The log shows the only filter which runs is gziptoany. gziptoany is designed to "Copy (and uncompress) files to stdout". The result is not unexpected because conversion is from mime type postscript to mime type postscript. Nothing much has happened here; move on, please!

How about

  /usr/sbin/cupsfilter -p laserjet2200.ppd -m application/pdf -o number-up=2 test.ps > out.ps 2> log ?

From the log we see Ghostscript converting PostScript to PDF with pstopdf. The output looks no different from the input though. That's also expected, so we progress to

  /usr/sbin/cupsfilter -p laserjet2200.ppd -m application/vnd.cups-pdf -o number-up=2 test.ps > out.pdf 2> log

to convert to a file suitable to be sent to a printer, maybe with some further processing.

We see pstopdf invoked again but it is followed by pdftopdf. The latter filter performs the very important task

Now we will alter the destination mime type:

  /usr/sbin/cupsfilter -p laserjet2200.ppd -m application/vnd.cups-postscript -o number-up=2 test.ps > out.ps 2> log

The only filter used is pstops and (in this example) it performs the same function as pdftopdf. This illustrates the older PostScript-centric workflow in action. Except for one or two situations, it will not happen on a Jessie printing syssem. Note that out.ps looks the same as out.pdf from previously; but do not run away with the idea that pstops does exactly the same thing as pdftopdf.

Obtaining the File which is Sent to the Printer

The last three commands have relied solely on the *.convs files in /usr/share/cups/mime to determine the filters used in the filtering chain. Each filter has a "cost". In the last command conversion to application/vnd.cups-postscript with pstops costs 66. This is the same cost as (pstopdf + pdftopdf +pdftops) but the number of filters is fewer. The former becomes the preferred route.

But filters can also be specified in the PPD file with a *cupsFilter line. Look at the laserjet.ppd; it has

  *cupsFilter "application/vnd.cups-raster 100 rastertogutenprint 5.2"

To use this filter with cupsfilter the "-e" option is required and the destination file type (-m) has to be one which the printer is happy with.

  /usr/sbin/cupsfilter -p laserjet2200.ppd -m printer/foo -o number-up=2 test.ps -e > out.pcl 2> log

A Problem with the hpcups Filter

Any use of an hpcups PPD file with the previous command on Jessie results in hpcups crashing. The reason is explained in LP #1395676.

One way to get round this is to use cupsfilter up to the application/vnd.cups-raster stage and then produce the printer-ready file with

  DEVICE_URI="" PPD="hpcups_ppd" /usr/lib/cups/filter/hpcups 0 0 0 0 0 <raster_file> > out.pcl

Alternatively, a version of printer-driver-hpcups greater than or equal to 3.15.2 from unstable (Sid) can be installed. libjpeg8 will also be required.

UNFINISHED.

TIDYING UP AND MORE MATERIAL TO COME