Created Date: 16 Mar, 2022 15:03
Last Modifed Date: 19 Sep, 2023 16:35

To view previous v13.x documentation, go to Manuals (v13).

This page applies to Harlequin v14.0r0 and later; and to Harlequin Core and Harlequin MultiRIP.

PostScript-language filters provide a method for transforming a data stream from one form to another. This allows implementation of data decompression and language translation facilities. [RB2] describes a number of filters built into the language (Section 3.13) and the nature of filters as implicit resources (Table 3.8 and Section 3.9.2).

In addition, the Harlequin RIP provides a mechanism that allows filters to be added by OEMs. Furthermore, externally implemented filters override those built in, so alternative algorithms can be defined for standard filters. This is especially useful where hardware accelerators are available (for example, to implement a JPEG DCTDecode filter).

This requires C coding to implement the filter algorithm and make it available to the RIP. The details depend on the version of the RIP: the method for integration with the Core RIP is given in DEVICE interface and with HMR in Filter plugins.

Once the compiled code is linked with the RIP, you must make the filter known to the PostScript language. This is common to all versions and is described here.

In the PostScript language, filters are represented as implicit resources. The Harlequin RIP extends this to make filters explicit resources that can be defined with the defineresource operator. In terms of [RB2], this means that the Filter category moves from Table 3.8 to Table 3.7. Also, its type in that table, though still a name for the purposes of everything that could previously have been done with it (the resource key—the name of the filter—and its value are actually the same), is a dictionary for defineresource. It is not allowed at all in that context if it were an implicit resource.

The dictionary dict contains two required keys, as follows:



If the filter is a decode filter, FilterType is the string (r) or (d) ; if an encode filter it is (w) or (e)



This identifies the device type which implements the filter. For GUI versions, this is the input plugin filter device, which is always type 16. Core-RIP implementations can use any unique number (according to the rules for device types that include the OEM number) and is different for each filter type.

Internally a filter is implemented as a non-relative device type. For filters, the defineresource is similar in operation to the devmount and associated setdevparams for devices (though not completely since a new device is created for each instantiation of the filter with the filter operator).

For example, consider creating a decode filter which converts UNIX-style uuencoded data to plain text consisting of PostScript-language code. The filter is made available by something like this:

            /HQNuudecode <<
            /FilterType (r)
            /FilterNumber 16
            >> /Filter defineresource pop

This code could appear:

  • in a start-up file such as Usr/Start or Sys/HqnOEM , if the filter needs to be available at all times
  • in a page feature, as discussed under Interpreting other page description languages
  • as part of a PostScript language job that needs to use the filter, if you have control over the job being sent
  • in a procedure invoked by some comments in a job, as discussed in Comment parsing, or
  • anywhere else PostScript language can be put, as appropriate.

You could then use filter to decode a file FILE.UU containing the uuencoded data as follows:

            /f (FILE.UU)(r) file def f /HQNuudecode filter
            cvx exec % execute the PostScript language read from the filter f closefile

Uses of filters can be wrapped up in procedures, which can make them look like operators. For example, consider:

(FILE.UU) uurun

where the definition of the procedure uurun is very similar to the example above.

Custom filters can have parameters, like built-in ones. For custom filters, these are always specified in a single dictionary between the src/tgt and name operands of the filter operator (as described in [RB2]), just as with the built-in DCTDecode filter. These parameters are handled internally analogously to parameters set by setdevparams for an ordinary device.