Skip to content

About

Ghostscript Printer Application

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

 
 

Latest commit

 

History

278 Commits

Folders and files

Repository files navigation

BLUEFIN DIRECTION

This will be a projectbluefin/fsdk-container designed to bring this to all Linuxes. It will be deployed by a quadlet.

  • Bluefin will ship this first
  • Many of the things in these containers are old school, modernize and bring it to fsdk specs, distroless. Slim and mean.

Ghostscript Printer Application

INTRODUCTION

This repository contains a Printer Application for printers supported by Ghostscript's built-in printer drivers and some extra filters.

It uses PAPPL to support IPP printing from multiple operating systems. In addition, it uses the resources of cups-filters 2.x (filter functions in libcupsfilters, libppd) and pappl-retrofit (encapsulating classic CUPS drivers in Printer Applications). This work (or now the code of pappl-retrofit) is derived from the hp-printer-app.

For printer capability and driver usage information the Foomatic database of OpenPrinting (Online access by printer, by driver, Downlod) is used.

For the Bluefin OCI appliance, report issues and propose changes to the testing branch of the Bluefin fork. For upstream application and Snap changes, use OpenPrinting.

Contained Printer Drivers

  • Ghostscript built-in:

    ap3250, appledmp, bj10e, bj10vh, bj10v, bj10, bj200, bj8XXYYZ.upp,
    bjc250gs, bjc600, bjc800, bjc880j, cdj500, cdj550, cdnj500, chp2200,
    cljet5, cp50, declj250, deskjet, dj505j, djet500, dnj650c,
    eplaser-jp, eplaser, eps9high, eps9mid, epsonc, epson, escpage,
    fmlbp, fmpr, gdi, hl1250, hl7x0, ibmpro, imagen, iwhi, jetp3852,
    jj100, la50, la70, la75plus, la75, laserjet, lbp310, lbp320, lbp8,
    lex5700, lex7000, lips2p, lips3, lips4v, lips4, lj250, lj4dithp,
    lj4dith, lj5gray, ljet2p, ljet3d, ljet3, ljet4d, ljet4, ljetplus,
    ln03, lp2000, lp2563, lp8000, lq850, lxm3200-tweaked, lxm5700m,
    m8510, md1xMono, md2k, md50Eco, md50Mono, md5k, mj700v2c, ml600,
    necp2xX.upp, necp6, npdl, oce9050, oki182, oki4w, okiibm, paintjet,
    pcl3, picty180, pjetxl, pjxl300, pjxl, pj, ps2write, pr150, pr201,
    pxlcolor, pxldpl, pxlmono, r4081, rpdl, sharp.upp, sipixa6.upp,
    sj48, stcolor, t4693dX, tek4696, xes
    

    This gives support for many old and ancient printers, but also for PCL lasers (especially PCL 6/XL) and dot-matrix printers.

    The included Ghostscript can have more drivers but these are the ones for which we have PPD support from Foomatic and which are not considered deprecated by another driver.

  • hpijs of HPLIP: For non-HP PCL printers (use the HPLIP Printer Application for HP printers). Better print quality than with Ghostscript's built-in drivers.

  • pnm2ppa: Driver for some older HP printers with proprietary protocol, probably the only HP printers NOT supported by HPLIP. even not with HP's proprietary plugin. Its configuration file is user-editable in persistent application state, see below.

  • pxljr: For HP Color LaserJet 3500/3550/3600, should give better output quality than HPLIP.

  • foo2zjs: Driver for laser printers with proprietary languages, from Dell, Epson, Fuji, HP, Kyocera, Lexmark, (Konica) Minolta, Oki, Olivetti, Ricoh, Samsung, Xerox. Note that the firmware loading facility for HP is not included in this Printer Application, use the HPLIP Printer Application (download proprietary plugin in-app, via web interface) for these printers, the firmware is proprietary anyway. Users can add color profiles in persistent application state, see below.

  • SpliX: Driver for laser printers with proprietary languages, from Dell, Lexmark, Samsung, Toshiba, Xerox

  • brlaser: Driver for Brother HL, DCP, and MFC laser printers which do not understand PostScript nor PCL.

  • fxlinuxprint: Driver from Fuji Xerox for their PDF printers before the times of driverless IPP.

  • c2esp: Driver for Kodak EasyShare printers.

  • rastertosag-gdi: For the few Ricoh models which do not do PostScript or PCL: Ricoh Aficio SP 1000S/1100S

  • dymo: Driver for Dymo's label printers

  • ptouch: Driver for Brother's P-Touch label printers

  • c2050, cjet, min12xxw, m2300w: Drivers for older Lexmark, Canon, and Minolta printers. Users can add m2300w color profiles in persistent application state, see below.

  • CUPS, cups-filters: Included drivers for PCL, dot-matrix (Oki, Epson), label printers (Dymo, Intellitech, Zebra), and some older HP DesignJet large-format printers.

  • Manufacturer-supplied PPD files: For PCL and PDF printers from Ricoh and OEM (Gestetner, InfoPrint, Infotec, Lanier, NRG, Ricoh, Savin) and from Samsung.

Not included

  • PostScript: For manufacturer-supplied PostScript support, use the PostScript Printer Application.

  • HPLIP: For practically all HP printers use the HPLIP Printer Application. It also supports HP's proprietary plugin for printers which need to load their firmware on startup or need a proprietary driver extension.

  • Gutenprint: High-quality output with inkjets from Epson, Canon, and others, also PCL laser printers. A lot of adjustable parameters. Use the Gutenprint Printer Application.

  • epson-inkjet-printer-escpr: Epson's free-software printer driver for ESC/P-R-based inkjet printers. It supports only 360 dpi resolution and a very awkward user interface which cannot get easily mapped to IPP. Therefore it is not included in this Printer Application. Use the Gutenprint Printer Application.

  • Braille embosser drivers: We plan a separate Printer Application for that.

  • Scanners in multi-function devices: We plan a SANE retro-fit Scanner Application.

Properties

  • A Printer Application providing Ghostscript-based printer drivers. Input data is converted to PDF or PostScript (if not already supplied in one of these formats) as these are the input data formats of Ghostscript, fed into Ghostscript and by Ghostscript converted into the printer's native language. In some cases Ghostscript produces generic raster output which is converted to the printer's language by an additional filter.

  • PWG Raster, Apple Raster or image input data is converted to PostScript and not to PDF as PostScript is streamable, and this way large jobs need less resources or one can theoretically even print infinite jobs.

  • This Printer Application also includes some separate, old and now unmaintained printer drivers which are too small projects for their own Printer Application. These can also consist of a CUPS Raster filter, not needing Ghostscript if the input is PWG Raster, Apple Raster, or an image.

  • Note that most of the drivers (both inside Ghostscript and separate filters) are old, unmaintained code, for old printers which we do not have access to for testing. The packaging in the Snap (and also in Debian where the Snap uses a Debian source) is minimum-invasive to assure formerly working code stays working, but it is not assured due to changes in GCC and the libraries or due to the Snap environment.

  • This Printer Application supports thousands of (usually older) printer models. The needed printer capability information and driver usage information is mainly taken from OpenPrinting's Foomatic database, but also from information which comes with individual drivers.

  • From the Foomatic data CUPS PPD files are pre-built, compressed and packaged with the Snap. Also the foomatic-rip filter of cups-filters, Ghostscript, and the extra printer driver filters are included. With this a CUPS driver retro-fit using the pappl-retrofit library is done. This way we do not need to modify or adapt the now mostly unmaintained printer driver code, nor the Foomatic data or the PPD files. This is important as we do not have the printers for testing.

  • We use the printer's IEEE-1284 device ID to identify manufacturer and model of the printer and look for explicit driver support for this model. If we do not find it, we check the CMD: field of the ID to see whetrher the printer supports any common data format, currently PostScript, PCL-6/XL, PCL 5c, and PCL 5e to select a generic driver.

  • Available printer devices are discovered (and used) with CUPS' backends and not with PAPPL's own backends. This way quirk workarounds for USB printers with compatibility problems are used (and are editable) and any driver's output can get sent to the printer via IPP, IPPS (encrypted!), and LPD in addition to socket (usually port 9100). The SNMP backend can get configured (community, address scope).

  • If you have an unusual system configuration or a personal firewall your printer will perhaps not get discovered. In this situation the fully manual "Network Printer" entry in combination with the hostname/IP field can be helpful.

  • Standard job IPP attributes are mapped to the driver's option settings best fitting to them so that users can print from any type of client (like for example a phone or IoT device) which only supports standard IPP attributes and cannot retrive the PPD options. Trays, media sizes, media types, and duplex can get mapped easily, but when it comes to color and quality it gets more complex, as relevant options differ a lot in the PPD files. Here we use an algorithm which automatically (who wants hand-edit ~10000 PPD files for the assignments) finds the right set of option settings for each combination of print-color-mode (color/monochrome), print-quality (draft/normal/high), and print-content-optimize (auto/photo/graphics/text/text-and-graphics) in the PPD of the current printer. So you have easy access to the full quality or speed of your printer without needing to deal with printer-specific option settings (the original options are still accessible via web admin interface).

To Do

THE SNAP

Installing and building

To just run and use this Printer Application, simply install it from the Snap Store:

sudo snap install --edge ghostscript-printer-app

Then follow the instructions below for setting it up.

To build the Snap by yourself, in the main directory of this repository run

snapcraft snap

This will download all needed packages and build the Ghostscript Printer Application. Note that PAPPL (upcoming 1.0) and cups-filters (upcoming 2.0) are pulled directly from their GIT repositories, as there are no appropriate releases yet. This can also lead to the fact that this Printer Application will suddenly not build any more.

To install the resulting Snap run

sudo snap install --dangerous ghostscript-printer-app_1.0_amd64.snap

Setting up

The Printer Application will automatically be started as a server daemon.

Enter the web interface

http://localhost:8000/

Use the web interface to add a printer. Supply a name, select the discovered printer, then select make and model. Also set the installed accessories, loaded media and the option defaults. Accessory configuration and option defaults can also offen get polled from the printer.

Then print PDF, PostScript, JPEG, Apple Raster, or PWG Raster files with

ghostscript-printer-app FILE

or print with CUPS, CUPS (and also cups-browsed) discover and treat the printers set up with this Printer Application as driverless IPP printers (IPP Everywhere and AirPrint).

See

ghostscript-printer-app --help

for more options.

Use the "-o log-level=debug" argument for verbose logging in your terminal window.

You can add files to /var/snap/ghostscript-printer-app/common/usb/ for additional USB quirk rules. Edit the existing files only for quick tests, as they get replaced at every update of the Snap (to introduce new rules).

You can edit the /var/snap/ghostscript-printer-app/common/cups/snmp.conf file for configuring SNMP network printer discovery.

For the pnm2ppa driver you can edit the configuration file:

/var/snap/ghostscript-printer-app/common/pnm2ppa/pnm2ppa.conf

For the foo2zjs and m2300w drivers you can add color profiles in the appropriate subdirectories of

/var/snap/ghostscript-printer-app/common/foo2zjs/
/var/snap/ghostscript-printer-app/common/m2300w/

Automatic firmware loading by foo2zjs is not supported. If you have one of these HP printers which need it, use the HPLIP Printer Application and download HP's plugin (use the web interface of the HPLIP Printer Application for that).

All the changes mentioned her take effect with the next print job.

If you mess up any configuration file under /var/snap/ghostscript-printer-app/common/, simply delete it (or move it away) and restart the Snap to get it restored.

OCI CONTAINER IMAGE

The OCI appliance is published only to the GitHub Container Registry. Each published commit on testing gets an immutable sha-<commit> tag and moves stable and the application-version tag <VERSION> (plus <VERSION>-x86_64 and <VERSION>-aarch64) to its signed index; there is no latest or edge OCI tag.

Run the published image

Install Podman with a working rootless user namespace, then run stable, or pin a sha-<commit> tag or digest instead:

image="ghcr.io/projectbluefin/ghostscript-printer-app:stable"
podman pull "$image"
podman volume create ghostscript-printer-app
podman run -d \
  --name ghostscript-printer-app \
  --network host \
  -e PORT=8000 \
  -v ghostscript-printer-app:/var/lib/ghostscript-printer-app:Z,U \
  "$image"

Open http://localhost:8000/ and use the web interface to add a printer. PORT is optional; without it, the application selects port 8000 or the next available port. Host networking is required for local-network printer discovery. The named volume preserves Printer Application state and user-edited driver configuration across upgrades. Startup uses umask 077 and restricts the CUPS, TLS-key, and spool directories to the runtime user (0700). Existing TLS and spool contents lose group/other access on every startup; a volume whose private state cannot be secured by UID/GID 65532:65532 fails startup. Keep bind-mounted state owned by that runtime user (the :U option above sets volume ownership), and restrict access to its host parent directory.

Web administration

PAPPL serves IPP and the web interface on the same port, and the appliance runs on host networking, so by default the web administration pages are reachable by every client that can reach the printer, without a credential. The entrypoint prints a NOTICE about this at startup. Close that surface with one of these environment variables; every value is validated, and a value the appliance cannot honour stops the container instead of starting it unauthenticated (exit 64 for a malformed value, 78 for a value this image cannot enforce):

Variable Forwarded as Accepted values
PRINTER_APP_SERVER_OPTIONS -o server-options=… Comma-separated PAPPL server options from the allow-list: no-web-interface.
PRINTER_APP_AUTH_SERVICE -o auth-service=… A PAM service name ([A-Za-z0-9_.-]). Refused with exit 78 while the image's PAPPL is built without PAM (see below).
PRINTER_APP_ADMIN_GROUP -o admin-group=… A group from the image's /etc/group; requires PRINTER_APP_AUTH_SERVICE.

PRINTER_APP_SERVER_OPTIONS=no-web-interface is the supported way to run the appliance on a LAN-facing surface today: every web page, including the per-printer configuration and pappl-retrofit's "Device Settings" pages, answers 404, while IPP printing, IPP administration from the container itself, and DNS-SD advertisement keep working. Manage printers with the command-line client from inside the container (podman exec ghostscript-printer-app ghostscript-printer-app -u ipp://127.0.0.1:8000/ipp/system … add):

podman run -d \
  --name ghostscript-printer-app \
  --network host \
  -e PORT=8000 \
  -e PRINTER_APP_SERVER_OPTIONS=no-web-interface \
  -v ghostscript-printer-app:/var/lib/ghostscript-printer-app:Z,U \
  "$image"

PRINTER_APP_AUTH_SERVICE and PRINTER_APP_ADMIN_GROUP are parsed so the configuration surface is stable for supervisors such as ChairLift, but the shared printing base builds PAPPL with --disable-libpam, so every service name is refused and the container exits 78 with a diagnostic naming no-web-interface as the alternative. The refusal does not depend on whether /etc/pam.d/<name> exists in the image (/etc/pam.d/cups ships with CUPS): forwarding auth-service to a PAM-less PAPPL would not authenticate anyone, it would answer every administration request, including from localhost, with 401. Authenticated web administration becomes available once the base builds PAPPL with PAM and ships a service configuration for this appliance.

Setting an unlisted server option such as no-tls or none, a name with characters outside [A-Za-z0-9_.-], a group PAPPL cannot resolve (it would otherwise skip the group check and admit every authenticated user), or a group without an auth service is rejected. tests/entrypoint-validation.sh covers those rejections on the host; tests/core-appliance.sh verifies the no-web-interface behaviour against the built image.

For USB printers, add these options to podman run:

--device /dev/bus/usb --group-add keep-groups

The host user must already have permission to access the printer device. Do not work around host permissions by running the appliance as root. Before starting, run python3 scripts/check-rootless-usb.py "$image" /dev/bus/usb/BBB/DDD with the printer's current node. See the rootless permissions and Quadlet setup for udev/group configuration, crun requirements, and a service that gates startup on this check.

Build and verify locally

The OCI image is built with BuildStream inside the pinned builder container. Install Podman and just, then run:

just build
just verify

just build exports and tags the local image as ghcr.io/projectbluefin/ghostscript-printer-app:build. just verify is the authoritative appliance gate: it checks the BuildStream graph and patch chain, starts the real image, exercises every driver slice, verifies lifecycle and persistence behavior, audits the advertised payload and complete ELF closure, and enforces the uncompressed size ceiling.

CUPS, cups-filters, libcupsfilters, libppd, Ghostscript, mutool, Avahi, PAPPL and pappl-retrofit come from the shared printing base of fsdk-containers (fsdk-containers.bst:printing/base.bst), junctioned at a pinned commit in elements/fsdk-containers.bst; FSDK itself comes through that junction. CI seeds the base from its cosign-verified printing-base-devel bundle, and Renovate (renovate.json) proposes and automerges junction bumps to fsdk-containers main once the merge queue's full gate passes.

For real hardware, follow the separate USB and network printer validation procedure. Synthetic CI results are not physical-printer evidence.

For driver and version differences against the current OpenPrinting Snap, see the Snap parity matrix.

Merge-queue CI and the publish workflow restore BuildStream's local cache (cas, artifacts, source_protos) from the Actions cache. The BuildStream cache refill workflow rebuilds and saves it per architecture on testing pushes and nightly (saved only when an arch fits in 9000 MB uncompressed; a larger cache skips the save with a warning and the run stays green); reset it with gh cache delete --all.

Development and releases

Open OCI development PRs against testing; Renovate's fsdk-containers bumps land there too. Pull requests run just validate, and the merge queue runs the full native amd64 and arm64 build and just verify before a change lands on testing. Retain main only while existing feature branches or workflows still reference it.

Every push to testing publishes: registry-actions.yml rebuilds and verifies native amd64 and arm64 images, then pushes, signs (index and both architecture manifests), attests and verifies everything by digest, including its SPDX SBOM, keyless signatures, GitHub provenance, and OCI metadata. The application version is derived at build time: the junction's Ghostscript release plus the packaging revision in VERSION (e.g. 10.07.1-4). IJS builds from that same Ghostscript source, and the FSDK version and ref labels come from the fsdk-containers junction, so a junction bump needs no other change. Only after every check passes does it create the immutable sha-<commit> tag and move <VERSION>, <VERSION>-x86_64, <VERSION>-aarch64 and stable, so a failed publication leaves no tagged, unsigned image. Publications run one at a time; pushes that queue behind a running one collapse to the newest, so an intermediate commit may have no sha-<commit> tag. Roll back by reverting the offending PR.

BUILDING WITHOUT PACKAGING OR INSTALLATION

You can also do a "quick-and-dirty" build without snapping and without needing to install PAPPL, cups-filters 2.x, and pappl-retrofit into your system. You need a directory with the latest GIT snapshot of PAPPL, the latest GIT snapshot of cups-filters, and the latest GIT snapshot of pappl-retrofit (master branches of each). They all need to be compiled (./autogen.sh; ./configure; make), installing not needed. Also install the header files of all needed libraries (installing "libcups2-dev" should do it).

In the directory with ghostscript-printer-app.c run the command line

gcc -o ghostscript-printer-app ghostscript-printer-app.c $PAPPL_SRC/pappl/libpappl.a $CUPS_FILTERS_SRC/.libs/libppd.a $CUPS_FILTERS_SRC/.libs/libcupsfilters.a $PAPPL_RETROFIT_SRC/.libs/libpappl-retrofit.a -ldl -lpthread  -lppd -lcups -lavahi-common -lavahi-client -lgnutls -ljpeg -lpng16 -ltiff -lz -lm -lusb-1.0 -lpam -lqpdf -lstdc++ -I. -I$PAPPL_SRC/pappl -I$CUPS_FILTERS_SRC/ppd -I$CUPS_FILTERS_SRC/cupsfilters -I$PAPPL_RETROFIT_SRC/pappl/retrofit -L$CUPS_FILTERS_SRC/.libs/ -L$PAPPL_RETROFIT_SRC/.libs/

There is also a Makefile, but this needs PAPPL, cups-filters 2.x, and pappl-retrofit to be installed into your system.

Run

./ghostscript-printer-app --help

When running the non-snapped version, by default, PPD files are searched for in

/usr/share/ppd/
/usr/lib/cups/driver/
/var/lib/ghostscript-printer-app/ppd/

You can set the PPD_PATHS environment variable to search other places instead:

PPD_PATHS=/path/to/my/ppds:/my/second/place ./ghostscript-printer-app server

Simply put a colon-separated list of any amount of paths into the variable. Creating a wrapper script is recommended.

This Printer Application uses CUPS' backends and not PAPPL's, meaning that for USB printers CUPS' USB quirk workarounds for compatibility problems are used, network printers can also be used with IPP, IPPS, and LPD protocols, and SNMP printer discovery is configurable.

USB Quirk rules in /usr/share/cups/usb and the /etc/cups/snmp.conf file can get edited if needed.

Make sure you have Ghostscript, CUPS (at least its backends), and the desired printer drivers (if not built into Ghostscript) installed.

For access to the test page testpage.ps use the TESTPAGE_DIR environment variable:

TESTPAGE_DIR=`pwd` PPD_PATHS=/path/to/my/ppds:/my/second/place ./ghostscript-printer-app server

or for your own creation of a test page (PostScript, PDF, PNG, JPEG, Apple Raster, PWG Raster):

TESTPAGE=/path/to/my/testpage/my_testpage.ps PPD_PATHS=/path/to/my/ppds:/my/second/place ./ghostscript-printer-app server

LEGAL STUFF

The Ghostcript Printer Application is Copyright © 2020 by Till Kamppeter.

It is derived from the HP PCL Printer Application, a first working model of a raster Printer Application using PAPPL. It is available here:

https://github.com/michaelrsweet/hp-printer-app

The HP PCL Printer Application is Copyright © 2019-2020 by Michael R Sweet.

This software is licensed under the Apache License Version 2.0 with an exception to allow linking against GPL2/LGPL2 software (like older versions of CUPS). See the files "LICENSE" and "NOTICE" for more information.

Source freshness, updater ownership and cache evidence are documented in the FSDK source update guide.

About

Ghostscript Printer Application

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages