Hi all -
The patch below unbreaks splix's rendering of the pdf content produced
when printing from Apple iOS devices (iPhone, iPad). Without this such
content causes the pstoqpdl filter to pass badly formatted content to
ghostscript, which makes it crash (and also appears to induce a kernel
panic in usblib1 if cups is using the usb backend).
The cause of the problem is that the postscript produced from such pdf
content, does not contain a '%%Creator' header line. This is a problem
for pstoqpdl, which uses that line to identify where to insert the
MediaType and colour correction information for what is passed to
ghostscript.
The patch improves pstoqpdl's slightly braindead method of scanning
the postscript header, and if there is no '%%Creator' line then it
creates a dummy one.
Tested with cups-1.6.2 and splix-2.0.0p7 on 5.3/i386 current of 31st
March.
Many thanks Antoine, for the cups usb patch :-)
I'll also submit this to the upstream developer when I get a chance.
MARTIN
ps: I hope this is the right way to do the diff/patch
==================
patch-src_pstoqpdl
==================
--- src/pstoqpdl.cpp.orig Fri Feb 6 11:49:10 2009
+++ src/pstoqpdl.cpp Sat Apr 6 21:40:18 2013
@@ -232,30 +232,86 @@ int main(int argc, char **argv)
fprintf(stdout, "%s", (char *)&buffer);
}
} else {
- // Check for the header
+
+ // Insert the MediaChoice and colour correction information into
+ // the postscript header.
+ //
+ // Look for a "%%Creator" line in the postscript header, and
+ // insert the information before it.
+ //
+ // Postscript that is created by pdftops from content from Apple
+ // iOS devices (iPad etc) seems not to have a "%%Creator" line in
+ // the header, so we insert a dummy one. Without this, pstoqpdl
+ // seems to crash ghostscript.
+ //
+ // NB: according to the PostScript Document Structuring Conventions
+ // (DSC) specification the end of the postscript header should be
+ // the "%%EndComments" line - see:
+ // http://partners.adobe.com/public/developer/en/ps/5001.DSC_Spec.pdf
+
+
+ // search each line in the postscript header
while (!(feof(stdin))) {
+
+ // read a line of the input file
if (!fgets((char *)&buffer, sizeof(buffer), stdin))
break;
- // End of the PS header ?
if (!(memcmp("%%Creator", (char *)&buffer, 9))) {
+ // found a "%%Creator" line
+
+ // emit the MediaChoice and colour correction information
if (paperType)
fprintf(stdout, "/MediaChoice (%s) def\n", paperType);
fprintf(stdout, "%s", crd);
fprintf(stdout, "%s", csa);
+
+ // emit the original "%%Creator" line
fprintf(stdout, "%s", (char *)&buffer);
+
+ // stop scanning the header
break;
+ }
- // End of the header not found?
- } else if (!(memcmp("%%%%BeginPro", (char *)&buffer, 10)) ||
- !(memcmp("%%BeginRes", (char *)&buffer, 10)) ||
- !(memcmp("%%EndComments", (char *)&buffer, 13))) {
+
+ if (!(memcmp("%%EndComments", (char *)&buffer, 13))) {
+ // reached end of header without finding a "%%Creator" line
+
+ // emit the MediaChoice and colour correction information
+ if (paperType)
+ fprintf(stdout, "/MediaChoice (%s) def\n", paperType);
+ fprintf(stdout, "%s", crd);
+ fprintf(stdout, "%s", csa);
+
+ // emit a dummy "%%Creator" line
+ DEBUGMSG(_("inserting dummy \"Creator\" entry in postscript
header"));
+ fprintf(stdout, "%s", "%%Creator: SpliX pstoqpdl filter");
+
+ // emit the original "%%EndComments" line
+ fprintf(stdout, "%s", (char *)&buffer);
+
+ // stop scanning the header
+ break;
+ }
+
+
+ if (!(memcmp("%%BeginPro", (char *)&buffer, 10)) ||
+ !(memcmp("%%BeginRes", (char *)&buffer, 10))) {
+ // we shouldn't find either of these lines in the header
+
ERRORMSG(_("End of PostScript header not found"));
+
+ // emit the line that was found
fprintf(stdout, "%s", (char *)&buffer);
+
+ // stop scanning the header
break;
}
+
+ // encountered some other kind of header line - just emit it
fprintf(stdout, "%s", (char *)&buffer);
}
+
// Check for each page
while (!(feof(stdin))) {