Bug 699397 - .locksafe breaks rendering of eps file with gs -dEPSCrop
Summary: .locksafe breaks rendering of eps file with gs -dEPSCrop
Status: RESOLVED INVALID
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: PS Interpreter (show other bugs)
Version: master
Hardware: PC Linux
: P4 normal
Assignee: Ken Sharp
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-06-04 08:21 UTC by Knut Petersen
Modified: 2018-06-05 16:42 UTC (History)
0 users

See Also:
Customer:
Word Size: ---


Attachments
TGZ with all the relevant files (76.00 KB, application/gzip)
2018-06-04 08:21 UTC, Knut Petersen
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Knut Petersen 2018-06-04 08:21:30 UTC
Created attachment 15219 [details]
TGZ with all the relevant files

In an attempt to improve the postscript code generated by lilypond I tumbled into a problem.

In the attached archive there are four almost identical (e)ps files, lockedsafe.eps  lockedsafe.ps  notlocked.eps  and notlocked.ps.

The only difference between the two ps files is that .locksafe is used or not, the same is true for the two eps files.

Rendering the the two ps files with gs master gives identical pdfs, as expected.

I believe that rendering the two eps files with 'gs -dEPSCrop' also should give identical results, but this is not the case. notlocked.eps gives the expected result, lockedsafe.eps gives an unexpected blank page.

Included in the archive you'll also find the script to generate the pdfs (mkall), two pdfs generated with 'mutool clean -d', a diff output and the font and the cmap used in the (e)ps files.

gs is git master e997c6836d243ab37fe3a5f0d57974af95eb5eac, built on an opensuse tumbleweed system.

I don't know if this is a regression.
Comment 1 Knut Petersen 2018-06-04 23:00:10 UTC
Apparently  the bounding box does not survive .locksafe. So I tried the following file header and succeeded: 

%!PS-Adobe-3.0 EPSF-2.0
SAFETY /safe get not {
<< 
/PermitFileWriting [ ]
/PermitFileControl [ ]
/PermitFileReading [
  (./*)
]
>> setuserparams 
 .locksafe
} if
%%BoundingBox: 28 -825 567 -18
[...]

Is this a bug? If it is not regarded as a bug it probably should be documented ...
Comment 2 Ken Sharp 2018-06-05 12:58:20 UTC
The report is somewhat confusing. The plethora of files in the archive makes it hard to know which files are required and which are not useful. The Lilypond PostScript program require certain files to be present, and in the current directory, but the only way to figure that out is to read the PostScript.

There isn't a Ghostscript command line supplied, which makes it difficult to know which device I should use for testing. Comment #0 refers to 'rendering' the two PostScript files, and then says that doing so gives identical PDFs, but PDF output doesn't render the input, so that's confusing.

Comment #0 also talks about 'an unexpectedly blank page' yet when I run the input EPS PostScript programs, no matter what configuration I use, I always get a blank page. So possibly I'm not running Ghostscript in exactly the same way, or there's something important I haven't been told.

Leaving aside the extraneous files it 'looks like' the complaint is that running something like:

gs -sDEVICE=pdfwrite -sOutputFile=1.pdf lockedsafe.eps

and:

gs -dEPSCrop -sDEVICE=pdfwrite -sOutputFile=2.pdf lockedsafe.eps

results in files which have the same media size.

When I try it here both PDF files are blank, but one has a MediaBox of 8.5x11 inches, the other has a MediaBox of 7.49x11.21. Checking the EPS BoundingBox we see that it is:

%%BoundingBox: 28 -825 567 -18

which corresponds to a width of 7.486 and a height of 11.208. So it looks to me like the sizes at least are correct.


In my opinion putting the .locksafe stuff in the PostScript files isn't really a great idea. It would be better to invoke Ghostscript with the .locksafe code on the command line. But nevertheless, I am unable to reproduce a problem.
Comment 3 Knut Petersen 2018-06-05 16:13:37 UTC
(In reply to Ken Sharp from comment #2)
> The report is somewhat confusing. The plethora of files in the archive makes
> it hard to know which files are required and which are not useful. The
> Lilypond PostScript program require certain files to be present, and in the
> current directory, but the only way to figure that out is to read the
> PostScript.
> 
> There isn't a Ghostscript command line supplied, which makes it difficult to
> know which device I should use for testing. Comment #0 refers to 'rendering'
> the two PostScript files, and then says that doing so gives identical PDFs,
> but PDF output doesn't render the input, so that's confusing.

As I wrote in the report there is the mkall script that contains the command lines used to produce all the included pdf files.

Emmentaler-20.cid is the font, Identity-H is the CMap used by all ps/eps files. 

The pdfs included in the tgz are the pdfs produced by mkall, the ps and eps files are the source files used. 

The two ps files only differ by the use of .locksafe, and both give the expected results. 

The two eps files also only differ by the use of .locksafe and also should give identical results. The pdf produced from notlocked.eps is obviously the desired
result, lockedsafe.eps only gives a blank page.

As I found out later (see comment 1) this can be fixed by moving .locksafe to a place before %%BoundingBox [...].

Although you changed the status to resolved/invalid I think it would be a good idea to at least document that the use of .locksafe throws away any prior knowledge of the desired bounding box. 

[ BTW: Maybe it also would be a good idea to document the fact that gs does not expand relative paths found in the PermitFileReading array to full paths.]

> In my opinion putting the .locksafe stuff in the PostScript files isn't
> really a great idea. It would be better to invoke Ghostscript with the
> .locksafe code on the command line. 

Well, I tried that first and learned the hard way that ghostscript uses '#define arg_str_max 2048 in base/gsargs.h'. My real PermitFileReading array is much bigger than the stripped down example ;-)

> But nevertheless, I am unable to reproduce a problem.

Sorry, I had hoped to be be clear.
Comment 4 Ken Sharp 2018-06-05 16:42:04 UTC
(In reply to Knut Petersen from comment #3)

> As I wrote in the report there is the mkall script that contains the command
> lines used to produce all the included pdf files.

But How am I to know that the PDF files represent the problem ? People often send me PDF files which contain things like screen shots of their problem.

While a script is undoubtedly useful if you are running on Linux its no use at all on Windows. We always prefer simplicity, so please put the command line in the bug report, where it can easily be read rather than supplying scripts which will only work with a specific operating system or scripting language.


> The two ps files only differ by the use of .locksafe, and both give the
> expected results. 

Since -dEPSCrop is not usable on PostScript files as opposed to EPS files), and that seems to be the source of your complaint, that's hardly surprising and their presence simply adds to the noise in the report.

 
> The two eps files also only differ by the use of .locksafe and also should
> give identical results. The pdf produced from notlocked.eps is obviously the
> desired
> result, lockedsafe.eps only gives a blank page.

Not for me, no. For me (as I said) both files produce blank output (on both Windows and Linux).


> Although you changed the status to resolved/invalid I think it would be a
> good idea to at least document that the use of .locksafe throws away any
> prior knowledge of the desired bounding box. 

If it did so, then I would document it. However for me it does not. The output of all the EPS files is blank for me, and when I use -dEPSCrop the 'locked' EPS file produces a differently sized output. So obviously the bounding box is *not* being thrown away, because that's what determines the output media size.


> > In my opinion putting the .locksafe stuff in the PostScript files isn't
> > really a great idea. It would be better to invoke Ghostscript with the
> > .locksafe code on the command line. 
> 
> Well, I tried that first and learned the hard way that ghostscript uses
> '#define arg_str_max 2048 in base/gsargs.h'. My real PermitFileReading array
> is much bigger than the stripped down example ;-)

Then use the @file syntax and put the command line in a file.

 
> > But nevertheless, I am unable to reproduce a problem.
> 
> Sorry, I had hoped to be be clear.

I closed the report as 'invalid' because I couldn't reproduce the problem you state (on Windows or Linux) given more information I can, now see what you are talking about, I'm afraid I just couldn't figure it out from the original report.

The documentation for .locksafe makes it *very* clear that it executes setpagedevice. So you can expect all the usual side effects of setpagedevice to take effect. This includes erasing the page, *and* resetting the graphics state, but *not* altering the PageSize.

The EPSCrop code works by resetting the PageSize to the values derived from the BoundingBox. It also modifies the CTM if necessary, although this is unusual. For your EPS, because you have a negative height, it *is* necessary.

When you reset the graphics state (due to executing .locksafe) you are doing it *after* the CTM has been recalculated, and it then gets reset, with the result that it isn't correct for your EPS file.

EPS files do not permit several kinds of operation, and one of the ones they don't permit is use of setpagedevice. So essentially by incorporating .locksafe into your EPS file you have turned it into an invalid EPS file (its executing operators its not permitted to).

So basically you need to do the setpagedevice before the CTM calculation. You can do it on the command line, before the %! in the PostScript program, or before the BoundingBox, though that's ugly.

I don't plan to document this specifically as its already quite clear in the documentation that .locksafe will execute setpagedevice, and that has quite a number of side effects which a PostScript programmer should be familiar with. Spelling out each of them would make the documentation unreadable.