Package: xpdf
Version: 3.02-1.4+lenny1
Severity: normal
Tags: patch
User: ubuntu-de...@lists.ubuntu.com
Usertags: origin-ubuntu karmic ubuntu-patch
In Ubuntu, we've applied the attached patch to achieve the following:
* pdftops produced wrong PostScript when a large image is in a
pattern in the input file
The relevant Ubuntu bug is https://launchpad.net/bugs/311982
We thought you might be interested in doing the same.
-- System Information:
Debian Release: squeeze/sid
APT prefers karmic-updates
APT policy: (500, 'karmic-updates'), (500, 'karmic-security'), (500,
'karmic-proposed'), (500, 'karmic-backports'), (500, 'karmic')
Architecture: i386 (i686)
Kernel: Linux 2.6.31-18-generic (SMP w/2 CPU cores)
Locale: LANG=ru_RU.UTF-8, LC_CTYPE=ru_RU.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
#! /bin/sh /usr/share/dpatch/dpatch-run
## do-not-make-ps-arrays-bigger-than-64k-from-big-images-in-patterns.dpatch by <till.kamppe...@gmail.com>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: No description.
@DPATCH@
diff -urNad xpdf-3.02~/xpdf/PSOutputDev.cc xpdf-3.02/xpdf/PSOutputDev.cc
--- xpdf-3.02~/xpdf/PSOutputDev.cc 2007-02-27 23:05:52.000000000 +0100
+++ xpdf-3.02/xpdf/PSOutputDev.cc 2009-01-02 18:08:43.000000000 +0100
@@ -2466,6 +2466,7 @@
GString *s;
int c;
int size, line, col, i;
+ int outerSize, outer;
// check if image is already setup
for (i = 0; i < imgIDLen; ++i) {
@@ -2552,56 +2553,72 @@
if (useRLE) {
++size;
}
+ outerSize = size/65535 + 1;
+
writePSFmt("{0:d} array dup /ImData_{1:d}_{2:d} exch def\n",
- size, id.num, id.gen);
+ outerSize, id.num, id.gen);
str->close();
// write the data into the array
str->reset();
- line = col = 0;
- writePS((char *)(useASCIIHex ? "dup 0 <" : "dup 0 <~"));
- do {
- do {
- c = str->getChar();
- } while (c == '\n' || c == '\r');
- if (c == (useASCIIHex ? '>' : '~') || c == EOF) {
- break;
- }
- if (c == 'z') {
- writePSChar(c);
- ++col;
- } else {
- writePSChar(c);
- ++col;
- for (i = 1; i <= (useASCIIHex ? 1 : 4); ++i) {
- do {
- c = str->getChar();
- } while (c == '\n' || c == '\r');
- if (c == (useASCIIHex ? '>' : '~') || c == EOF) {
- break;
- }
+ for (outer = 0;outer < outerSize;outer++) {
+ int innerSize = size > 65535 ? 65535 : size;
+
+ // put the inner array into the outer array
+ writePSFmt("{0:d} array 1 index {1:d} 2 index put\n",
+ innerSize, outer);
+ line = col = 0;
+ writePS((char *)(useASCIIHex ? "dup 0 <" : "dup 0 <~"));
+ for (;;) {
+ do {
+ c = str->getChar();
+ } while (c == '\n' || c == '\r');
+ if (c == (useASCIIHex ? '>' : '~') || c == EOF) {
+ break;
+ }
+ if (c == 'z') {
writePSChar(c);
++col;
+ } else {
+ writePSChar(c);
+ ++col;
+ for (i = 1; i <= (useASCIIHex ? 1 : 4); ++i) {
+ do {
+ c = str->getChar();
+ } while (c == '\n' || c == '\r');
+ if (c == (useASCIIHex ? '>' : '~') || c == EOF) {
+ break;
+ }
+ writePSChar(c);
+ ++col;
+ }
+ }
+ // each line is: "dup nnnnn <~...data...~> put<eol>"
+ // so max data length = 255 - 20 = 235
+ // chunks are 1 or 4 bytes each, so we have to stop at 232
+ // but make it 225 just to be safe
+ if (col > 225) {
+ writePS((char *)(useASCIIHex ? "> put\n" : "~> put\n"));
+ ++line;
+ if (line >= innerSize) break;
+ writePSFmt((char *)(useASCIIHex ? "dup {0:d} <" : "dup {0:d} <~"), line);
+ col = 0;
}
}
- // each line is: "dup nnnnn <~...data...~> put<eol>"
- // so max data length = 255 - 20 = 235
- // chunks are 1 or 4 bytes each, so we have to stop at 232
- // but make it 225 just to be safe
- if (col > 225) {
+ if (c == (useASCIIHex ? '>' : '~') || c == EOF) {
writePS((char *)(useASCIIHex ? "> put\n" : "~> put\n"));
- ++line;
- writePSFmt((char *)(useASCIIHex ? "dup {0:d} <" : "dup {0:d} <~"), line);
- col = 0;
+ if (useRLE) {
+ ++line;
+ writePSFmt("{0:d} <> put\n", line);
+ } else {
+ writePS("pop\n");
+ }
+ break;
}
- } while (c != (useASCIIHex ? '>' : '~') && c != EOF);
- writePS((char *)(useASCIIHex ? "> put\n" : "~> put\n"));
- if (useRLE) {
- ++line;
- writePSFmt("{0:d} <> put\n", line);
- } else {
writePS("pop\n");
+ size -= innerSize;
}
+ writePS("pop\n");
str->close();
delete str;
@@ -4215,7 +4232,7 @@
delete str;
} else {
// set up to use the array already created by setupImages()
- writePSFmt("ImData_{0:d}_{1:d} 0\n", ref->getRefNum(), ref->getRefGen());
+ writePSFmt("ImData_{0:d}_{1:d} 0 0\n", ref->getRefNum(), ref->getRefGen());
}
}
@@ -4676,7 +4693,7 @@
delete str2;
} else {
// set up to use the array already created by setupImages()
- writePSFmt("ImData_{0:d}_{1:d} 0\n", ref->getRefNum(), ref->getRefGen());
+ writePSFmt("ImData_{0:d}_{1:d} 0 0\n",ref->getRefNum(), ref->getRefGen());
}
}
@@ -4730,7 +4747,12 @@
// data source
if (mode == psModeForm || inType3Char || preload) {
- writePS(" /DataSource { 2 copy get exch 1 add exch }\n");
+ if (inlineImg) {
+ writePS(" /DataSource { 2 copy get exch 1 add exch }\n");
+ } else {
+ writePS(" /DataSource { dup 65535 ge { pop 1 add 0 } if 2 index 2"
+ " index get 1 index get exch 1 add exch }\n");
+ }
} else {
writePS(" /DataSource currentfile\n");
}
@@ -4769,6 +4791,7 @@
writePSFmt(">>\n{0:s}\n", colorMap ? "image" : "imagemask");
// get rid of the array and index
+ if (!inlineImg) writePS("pop ");
writePS("pop pop\n");
} else {
@@ -4944,7 +4967,7 @@
delete str2;
} else {
// set up to use the array already created by setupImages()
- writePSFmt("ImData_{0:d}_{1:d} 0\n", ref->getRefNum(), ref->getRefGen());
+ writePSFmt("ImData_{0:d}_{1:d} 0 0\n", ref->getRefNum(), ref->getRefGen());
}
}
@@ -5015,7 +5038,12 @@
// data source
if (mode == psModeForm || inType3Char || preload) {
- writePS(" /DataSource { 2 copy get exch 1 add exch }\n");
+ if (inlineImg) {
+ writePS(" /DataSource { 2 copy get exch 1 add exch }\n");
+ } else {
+ writePS(" /DataSource { dup 65535 ge { pop 1 add 0 } if 2 index 2"
+ " index get 1 index get exch 1 add exch }\n");
+ }
} else {
writePS(" /DataSource currentfile\n");
}
@@ -5151,6 +5179,7 @@
// get rid of the array and index
if (mode == psModeForm || inType3Char || preload) {
+ if (!inlineImg) writePS("pop ");
writePS("pop pop\n");
// image data