Bug 690101 - Problems when using the "cups" output device with PDF input
Summary: Problems when using the "cups" output device with PDF input
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: CUPS driver (show other bugs)
Version: 8.63
Hardware: All Linux
: P4 critical
Assignee: Michael Sweet
QA Contact: Bug traffic
Depends on:
Reported: 2008-09-30 03:01 UTC by Till Kamppeter
Modified: 2008-12-19 08:31 UTC (History)
3 users (show)

See Also:
Word Size: ---

pdftoraster.c (16.88 KB, text/plain)
2008-09-30 03:03 UTC, Till Kamppeter
gutenprint.ppd (23.37 KB, text/plain)
2008-09-30 03:06 UTC, Till Kamppeter
walking-map-portland-1.pdf (266.00 KB, application/pdf)
2008-09-30 03:07 UTC, Till Kamppeter
raster.out (7.33 MB, text/plain)
2008-09-30 03:13 UTC, Till Kamppeter
raster.err (31.75 KB, text/plain)
2008-09-30 03:19 UTC, Till Kamppeter
raster-debug.err (423.80 KB, text/plain)
2008-09-30 03:51 UTC, Till Kamppeter
raster-NOMEDIAATTRS-debug.err (22.28 KB, text/plain)
2008-09-30 03:53 UTC, Till Kamppeter
x.err (412.62 KB, text/plain)
2008-10-01 03:16 UTC, Till Kamppeter
gs-valgrind (491.27 KB, text/plain)
2008-10-02 10:24 UTC, Till Kamppeter
gs-valgrind-debug (740.35 KB, text/plain)
2008-10-02 11:04 UTC, Till Kamppeter
gdevcups.c (117.74 KB, text/plain)
2008-10-06 09:46 UTC, Till Kamppeter
gdevcups_wrong.c (117.60 KB, text/plain)
2008-10-16 22:45 UTC, Kai-Uwe Behrmann
gdevcups.c (117.60 KB, text/plain)
2008-10-16 22:55 UTC, Kai-Uwe Behrmann

Note You need to log in before you can comment on or make changes to this bug.
Description Till Kamppeter 2008-09-30 03:01:12 UTC
I have tried to create a "pdftoraster" CUPS filter based on Ghostscript (source
is attached, to compile with "gcc -I/usr/include/cups -o pdftoraster -lcups
-lcupsimage pdftoraster.c"). As one cannot embed PostScript commands in PDF
files I let the filter extract the "setpagedevice" dictionary settings from the
PPD file using cupsRasterInterpretPPD() from libcupsimage and build an
appropriate Ghostscript command line with all settings supplied as command line
arguments which I then execute.

Doing this manually looks like this:

cat walking-map-portland-1.pdf | PPD=/etc/cups/ppd/gutenprint.ppd /usr/bin/gs
-dQUIET -dPARANOIDSAFER -dNOPAUSE -dBATCH -sDEVICE=cups -sstdout=%stderr
-sOutputFile=%stdout -I/usr/share/cups/fonts -sMediaClass=Standard -r300x300
-dcupsColorOrder=0 -dcupsColorSpace=0 -dcupsCompression=3 -dcupsRowFeed=3
-scupsPageSizeName=A4 -c -f -_ > raster.out 2> raster.err

This Ghostscript command line is the one generated by
/etc/cups/ppd/gutenprint.ppd (attached) and I attach also

The file gets printed, somewhat shifted to the right, but after the rendering of
the file a GhostScript error occors. See attached raster.err file.

Adding "-dNOMEDIAATTRS" leads to nothing to get printed.
Comment 1 Till Kamppeter 2008-09-30 03:03:46 UTC
Created attachment 4444 [details]

First prototype of a Ghostscript-based pdftoraster filter for CUPS
Comment 2 Till Kamppeter 2008-09-30 03:06:05 UTC
Created attachment 4445 [details]

PPD file used for the test (of Gutenprint 5.2.0beta4)
Comment 3 Till Kamppeter 2008-09-30 03:07:20 UTC
Created attachment 4446 [details]

PDF input file used for the test
Comment 4 Till Kamppeter 2008-09-30 03:13:19 UTC
Created attachment 4447 [details]

CUPS Raster output of the test command line.
Comment 5 Till Kamppeter 2008-09-30 03:19:46 UTC
Created attachment 4448 [details]

STDERR output of the test command line
Comment 6 Till Kamppeter 2008-09-30 03:51:41 UTC
Created attachment 4449 [details]

Like raster.err, but now with "-dDEBUG" added to the Ghostscript command line
Comment 7 Till Kamppeter 2008-09-30 03:53:53 UTC
Created attachment 4450 [details]

This is the error output with both "-dDEBUG" and "-dNOMEDIAATTRS" added
Comment 8 Till Kamppeter 2008-09-30 04:05:54 UTC
As one can see at the lines commented out in pdftoraster.c one can see that I
have already tested more things:

- Supplying Postscript commands for the imaging bounding box and margins does
not prevent from the error and the Ghostscript output device should find this
info by itself, as it reads the PPD file.

- Supplying "-dSeparations=false" or "-dcupsNumColors=..." leads to other errors.

Comment 9 Till Kamppeter 2008-09-30 06:14:27 UTC
One remark on how I supplied PostScript commands: I used the "-c" command line

gs ... -c '<</cupsImagingBBox[10.0000 12.0000 585.0000 830.0000]>>setpagedevice'
'<</ImagingBoundingBox[10 12 585 830]>>setpagedevice' '<</Margins[10
12]>>setpagedevice' -f -_

Note that after supplying PostScript code with "-c" the "-f" option has to be
used to let Ghostscript return to interpret command line areguments as input
file names.

The shown settings cannot be supplied with the "-d" or "-s" command line options
as their values are arrays. "-d" or "-s" support only simple boolean, numerical,
or string values.
Comment 10 Till Kamppeter 2008-09-30 09:01:57 UTC
I have also tried to feed PostScript (the CUPS test page) into the shown
Ghostscript command lines and then Ghostscript renders the input without any
errors. So the problem is some bad interference when PDF is rendered with the
"cups" output device.
Comment 11 Till Kamppeter 2008-09-30 09:37:03 UTC
I had a look at bug 690032 and this bug seems to have the same "fingerprint". If
I run

gs -sDEVICE=cups -sOutputFile=x ~/walking-map-portland-1.pdf

and press Enter at the prompt I get the same error output as with the command
line shown in bug 690032. The stacks shown in the message have practically the
same content, except some of the numerical parameters of the "--dict:...--" items.

Error message of

gs -sDEVICE=cups -sOutputFile=x ~/walking-map-portland-1.pdf

Error: /rangecheck in .installpagedevice
Operand stack:
   --nostringval--   false   --nostringval--   --dict:109/128(ro)(L)--  
Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--  
--nostringval--   2   %stopped_push   --nostringval--   --nostringval--  
--nostringval--   false   1   %stopped_push   1905   1   3   %oparray_pop   1904
  1   3   %oparray_pop   1888   1   3   %oparray_pop   --nostringval--  
--nostringval--   2   1   1   --nostringval--   %for_pos_int_continue  
--nostringval--   1834   3   7   %oparray_pop   --nostringval--   1818   3   7 
 %oparray_pop   --nostringval--   --nostringval--
Dictionary stack:
   --dict:1150/1684(ro)(G)--   --dict:1/20(G)--   --dict:97/200(L)--  
--dict:97/200(L)--   --dict:106/127(ro)(G)--   --dict:275/300(ro)(G)--  
Current allocation mode is local
Last OS error: 2
GPL Ghostscript 8.63: Unrecoverable error, exit code 1

Error message of

gs -sDEVICE=bjc600 -sOutputFile=x ~/walking-map-portland-1.pdf

Error: /rangecheck in .installpagedevice
Operand stack:
   --nostringval--   false   --nostringval--   --dict:59/72(ro)(L)--  
Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--  
--nostringval--   2   %stopped_push   --nostringval--   --nostringval--  
--nostringval--   false   1   %stopped_push   1905   1   3   %oparray_pop   1904
  1   3   %oparray_pop   1888   1   3   %oparray_pop   --nostringval--  
--nostringval--   2   1   1   --nostringval--   %for_pos_int_continue  
--nostringval--   1834   3   7   %oparray_pop   --nostringval--   1818   3   7 
 %oparray_pop   --nostringval--   --nostringval--
Dictionary stack:
   --dict:1153/1684(ro)(G)--   --dict:1/20(G)--   --dict:97/200(L)--  
--dict:97/200(L)--   --dict:106/127(ro)(G)--   --dict:275/300(ro)(G)--  
Current allocation mode is local
Last OS error: 2
GPL Ghostscript 8.63: Unrecoverable error, exit code 1

In both cases the size of the output file x suggests that the job got actually

So it is not excluded that Ghostscript has a general bug in rendering PDF, but
it is also possible that some drivers ("cups", "bjc600", "bjc800", ...?) have
bugs which trigger the same error.
Comment 12 Till Kamppeter 2008-10-01 03:14:36 UTC
I have done some more investigations. If you run

gs -sDEVICE=cups -sOutputFile=x <file>

everything works fime with any PostScript file. If you supply a PDF file, the
error shown in comment #11 always occurs on the second page. The first page gets
always printed. So one-page documents get correctly printed but Ghostscript
exits with an error exit value. On multiple-page documents only the first page
comes out.

The problem seems to be in the parameter list. For the first page it gets
correctly set up. From the second page on the parameter list is messed up and so
gdev_prn_put_params() gives the error.

You can see it if you run the above command line with "-dDEBUG":

gs -dDEBUG -dNOPAUSE -sDEVICE=cups -sOutputFile=x ~/walking-map-portland-1.pdf
>x.err 2>&1

You see in the attached x.err that shortly before the error occurs, the
parameter list contains items where the names are composed of random non-ASCII
characters. This happens even on the two last calls of gdev_prn_put_params() (a
call of gdev_prn_put_params() usually happens shortly after "DEBUG: max_color",
when lines not beginning with "DEBUG" appear).

It seems that the parameter list gets overwritten with unrelated data after the
first page or not correctly initialized for the second page.

Comment 13 Till Kamppeter 2008-10-01 03:16:02 UTC
Created attachment 4455 [details]

GhostScript error output for command line above
Comment 14 Till Kamppeter 2008-10-02 10:24:00 UTC
Created attachment 4461 [details]

Ran Ghostscript through valgrind:

valgrind gs -dDEBUG -dNOPAUSE -sDEVICE=cups -sOutputFile=gs.out
~/walking-map-portland-1.pdf >gs-valgrind 2>&1

Valgrind output attached.
Comment 15 Ralph Giles 2008-10-02 10:30:59 UTC
The valgrind trace shows a problem in cups_put_params() which suggests it is a
corruption problem inside gdevcups.
Comment 16 Till Kamppeter 2008-10-02 11:04:32 UTC
Created attachment 4463 [details]

Valgrind output with above command line but with gs built in debug mode
Comment 17 Kai-Uwe Behrmann 2008-10-06 08:58:45 UTC
Are the param_read_float() and familiy return values documented?
I'd like to know what is in the gs_param_list * plist, but it seems
to be a complicated thing.
Comment 18 Ralph Giles 2008-10-06 09:14:09 UTC
Kai-Uwe @17: The plist api is documented in gsparam.h. Or perhaps I should say,
what documentation there is, is there. It's also helpful to look at some
examples in of how it's used by some of the output devices.

In particular, gsparam.h says:

 *      - 'reading' procedures ('put' operations from the client's viewpoint)
 * return 1 for a missing parameter, 0 for a valid parameter, <0 on error.
 *      - 'writing' procedures ('get' operations from the client's viewpoint)
 * return 0 or 1 if successful, <0 on error.

Ghostscript API documentation is generally in header files, except for the
client and device apis which are described in doc/API.htm and doc/Drivers.htm
Comment 19 Till Kamppeter 2008-10-06 09:46:45 UTC
Created attachment 4469 [details]

Attached is a version of cups/gdevcups.c where I have done some small casting
fixes. Unfortunately, this did not fix this bug.
Comment 20 Kai-Uwe Behrmann 2008-10-16 22:34:20 UTC
When the code below param_write_int(plist, "cupsNumColors" ... in
cups_get_params():~830 is outcommented, the backend runs cleanly.
I could not check the resulting output. 

Without that following error occurs:
DEBUG2: before gdev_prn_put_params()
DEBUG2: error gdev_prn_put_params() -21
Error: /rangecheck in .installpagedevice
Operand stack:
   --nostringval--   false   --nostringval--   --dict:125/144(ro)(L)--  
Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--  
--nostringval--   2   %stopped_push   --nostringval--   --nostringval--  
--nostringval--   false   1   %stopped_push   1905   1   3   %oparray_pop   1904
  1   3   %oparray_pop   1888   1   3   %oparray_pop   --nostringval--  
--nostringval--   2   1   1   --nostringval--   %for_pos_int_continue  
--nostringval--   1834   3   7   %oparray_pop   --nostringval--   1818   3   7 
 %oparray_pop   --nostringval--   --nostringval--
Dictionary stack:
   --dict:1147/1684(ro)(G)--   --dict:1/20(G)--   --dict:75/200(L)--  
--dict:75/200(L)--   --dict:106/127(ro)(G)--   --dict:275/300(ro)(G)--  
Current allocation mode is local
Last OS error: 2
GPL Ghostscript 8.63: Unrecoverable error, exit code 1
DEBUG2: cups_close(0x8d95144)

My guess is that the gs_param_list stuff is messed up.
Can this be veryfied or falsified? How?
Comment 21 Kai-Uwe Behrmann 2008-10-16 22:45:56 UTC
Created attachment 4512 [details]

This version allows to run through cups output with a simple PDF like
tiger.pdf (from tiger.eps). Several param_write_xxx calls are omitted in
this version.

The error code of 
DEBUG2: before gdev_prn_put_params()
DEBUG2: error gdev_prn_put_params() -21
is defined as "gs_error_undefined".
Comment 22 Kai-Uwe Behrmann 2008-10-16 22:55:41 UTC
Created attachment 4513 [details]

Correct test version to run cups.
Comment 23 Till Kamppeter 2008-10-17 09:50:47 UTC
Fixed in revision 9165. Fixed broken duplex in addition.
Comment 24 Till Kamppeter 2008-10-17 13:44:54 UTC
As the "cups" output device is working with PDF input now, I have added a
pdftoraster filter to the SVN repository (to build with "make cups" and to
install together with the other CUPS files with "make install-cups".

This filter can be used with the other PDF filters from OpenPrinting to have a
PDF-based printing workflow:


And thank you for all the help and contributions to make me fix this bug.