Bug 692665

Summary: [PATCH] Proposed device to compute ink coverage of a document
Product: Ghostscript Reporter: Sebastian Kapfer <sebastian.kapfer>
Component: GeneralAssignee: Marcos H. Woehrmann <marcos.woehrmann>
Status: RESOLVED FIXED    
Severity: enhancement CC: chris.liddell, pipitas
Priority: P4    
Version: master   
Hardware: All   
OS: All   
Customer: Word Size: ---
Attachments: Patch implementing this

Description Sebastian Kapfer 2011-11-06 13:06:24 UTC
For the puposes of print accounting it is sometimes useful to compute the ink coverage of a PS document.  For example, Pykota (http://www.pykota.com/) accomplishes this by converting the document to TIFF (using Ghostscript) and counting the pixels in the end.  Unfortunately, the TIFFs produced tend to be rather large for big print jobs, and disk I/O slows down the whole process.

To solve this problem, I propose to add a dummy device to Ghostscript which does the ink coverage analysis on the fly, without the need to dump all the pages to TIFFs first.  The 'output' of this device is the ink coverage analysis rather than a readable document.  The whole thing is similar to the existing 'bbox' device.

I have implemented this in the attached patch, and the code is minimal.  Would such a device qualify for inclusion in Ghostscript upstream?

The patch has been tested now for a week with a large number of users, and in our setup gives a 10- to 60-fold improvement for large print jobs over the TIFF kludge that was in place before.  I have a wrapper script which does the integration into Pykota, as a drop-in replacement for pkpgcounter.

Best,
    Sebastian
Comment 1 Sebastian Kapfer 2011-11-06 13:10:30 UTC
Created attachment 8081 [details]
Patch implementing this

As sent to the gs-devel list
Comment 2 Sebastian Kapfer 2011-11-06 13:16:55 UTC
Chris Lidell wrote:

> Also, include in the report whether you would be willing to transfer
> copyright to Artifex software (which would be preferable for us,
> obviously!), or whether you'd want it distributed under the GPL license.

Copyright assignment to Artifex is not a problem for me.

> Finally, just a quick point I noticed your code uses the file operations
> from the standard C library directly, and we generally prefer that such IO
> happens through Ghostscript's own file APIs, as it keeps as much code as
> possible platform independent, and makes porting *much* easier.

This I don't quite understand, the C library functions should be very portable, no?

Am I supposed to use FAPIU* from gxfapi.h instead?  There doesn't seem to be a 'fprintf' function there, unfortunately.

Cheers,
  Sebastian
Comment 3 Marcos H. Woehrmann 2011-12-08 18:44:41 UTC
Assigned to Marcos to test with our standard test files for crashes.
Comment 4 Marcos H. Woehrmann 2011-12-09 03:05:41 UTC
I've tested the device and it appears to work as advertised with no problem.  I've contacted Miles to follow-up on the copyright assignment.
Comment 6 Marcos H. Woehrmann 2011-12-11 00:57:40 UTC
Thanks to Sebastian Kapfer for the code and the copyright assignment.
Comment 7 pipitas 2011-12-12 21:31:25 UTC
Will this device also work for GhostPDL (gxps, pcl6, gsvg)?
Comment 8 Sebastian Kapfer 2011-12-13 12:35:16 UTC
> Will this device also work for GhostPDL (gxps, pcl6, gsvg)?

That would be very desirable.  Does the device need to be very different to achieve that?
Comment 9 Chris Liddell (chrisl) 2011-12-13 12:45:07 UTC
Devices are in the "graphics library" which is (generally) PDL angnostic, so the device will work fine with PCL/PXL/XPS. The only thing is, it may not be included in the builds for for the GhostPDL products by default, so it might need added.
Comment 10 pipitas 2011-12-15 15:16:48 UTC
I've been trying to get it to work with a current local build from today's Git checkout. But I seem to be missing something. The inkcov device appears in the list of "gs -h"  output. But my command

   gs -dNODISPLAY -sDEVICE=inkcov X.pdf

doesn't return anything (other than the Ghostscript version signature on stderr and "Page 1").
Comment 11 pipitas 2011-12-15 15:23:42 UTC
I've been trying to get it to work with a current local build from today's Git checkout. But I seem to be missing something. The inkcov device appears in the list of "gs -h"  output. But my command

   gs -dNOPAUSE -dBATCH -dNODISPLAY -sDEVICE=inkcov X.pdf

doesn't return anything (other than the Ghostscript version signature on stderr, plus "Page 1"). 

Skipping the '-dNODISPLAY' part yields this:

kp@mro:~/$  gs -sDEVICE=inkcov -dNOPAUSE -dBATCH X.pdf 
GPL Ghostscript GIT PRERELEASE 9.05 (2011-03-30)
Copyright (C) 2010 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
GPL Ghostscript GIT PRERELEASE 9.05: **** Could not open the file  .
Error: /invalidfileaccess in --showpage--
Operand stack:
   1   true
Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   --nostringval--   false   1   %stopped_push   1894   1   3   %oparray_pop   1893   1   3   %oparray_pop   1877   1   3   %oparray_pop   --nostringval--   --nostringval--   2   1   1   --nostringval--   %for_pos_int_continue   --nostringval--   --nostringval--   1777   0   9   %oparray_pop   --nostringval--   --nostringval--
Dictionary stack:
   --dict:1157/1684(ro)(G)--   --dict:1/20(G)--   --dict:82/200(L)--   --dict:82/200(L)--   --dict:109/127(ro)(G)--   --dict:291/300(ro)(G)--   --dict:24/31(L)--   --dict:6/8(L)--   --dict:21/40(L)--
Current allocation mode is local
Last OS error: 2
GPL Ghostscript GIT PRERELEASE 9.05: Unrecoverable error, exit code 1
Comment 12 Ken Sharp 2011-12-15 15:28:31 UTC
(In reply to comment #11)

> Skipping the '-dNODISPLAY' part yields this:
> 
> kp@mro:~/$  gs -sDEVICE=inkcov -dNOPAUSE -dBATCH X.pdf 
> GPL Ghostscript GIT PRERELEASE 9.05 (2011-03-30)
> Copyright (C) 2010 Artifex Software, Inc.  All rights reserved.
> This software comes with NO WARRANTY: see the file PUBLIC for details.
> Processing pages 1 through 1.
> Page 1
> GPL Ghostscript GIT PRERELEASE 9.05: **** Could not open the file  .
> Error: /invalidfileaccess in --showpage--

Try setting -sOutputFile=...
Comment 13 Chris Liddell (chrisl) 2011-12-15 16:23:27 UTC
You *might* also have to leave off the -dNODISPLAY, IIRC, that installs the null page device.
Comment 14 pipitas 2011-12-15 22:22:45 UTC
Thanks to Ken's hint I now found the shortest way to display a result:

   gs -o - -sDEVICE=inkcov X.pdf

Which, in my case returns:

Page 1
Substituting font Helvetica for ArialMT.
Substituting font Helvetica-Oblique for Arial-ItalicMT.
Substituting font Helvetica-Bold for Arial-BoldMT.
 0.00000  0.00000  0.00000  0.07180 CMYK OK
Page 1
Substituting font Helvetica for ArialMT.
Substituting font Helvetica-Bold for Arial-BoldMT.
Substituting font Helvetica-Oblique for Arial-ItalicMT.
Substituting font Times-Italic for TimesNewRomanPS-ItalicMT.
Substituting font Times-Roman for TimesNewRomanPSMT.
 0.00000  0.00000  0.00000  0.05719 CMYK OK
Page 1
Substituting font Helvetica for ArialMT.
Substituting font Helvetica-Bold for Arial-BoldMT.
Substituting font Helvetica-Oblique for Arial-ItalicMT.
Substituting font Times-Italic for TimesNewRomanPS-ItalicMT.
Substituting font Times-Roman for TimesNewRomanPSMT.
 0.00000  0.00000  0.00000  0.05349 CMYK OK


These commands also work as expected:

   gs -o X_inkcov.txt -sDEVICE=inkcov Y.pdf
   gs -o X_inkcov_page%03d.txt -sDEVICE=inkcov Y.pdf

Kudos to Sebastian for adding an extremely useful tool/device to Ghostscript. Not everybody will have a use for it, but those who do will kiss his feet :-)

I'll give it a better spin over the next few weeks, put it through my testing, and report back any issues I find.