Commit 6ee907f2 authored by Albert Astals Cid's avatar Albert Astals Cid

[xpdf303] More merges from Thomas, basically PSOutputDev and some other small stuff

parent 4fcd42cf
......@@ -729,7 +729,7 @@ GfxFontLoc *GfxFont::locateFont(XRef *xref, GBool ps) {
if (!isCIDFont()) {
//----- 8-bit PS resident font
if (ps) {
if (name && ps) {
if ((path = globalParams->getPSResidentFont(name))) {
fontLoc = new GfxFontLoc();
fontLoc->locType = gfxFontLocResident;
......@@ -756,7 +756,7 @@ GfxFontLoc *GfxFont::locateFont(XRef *xref, GBool ps) {
substName = new GooString(base14SubstFonts[substIdx]);
if (ps) {
error(errSyntaxWarning, -1, "Substituting font '{0:s}' for '{1:t}'",
base14SubstFonts[substIdx], name);
base14SubstFonts[substIdx], name ? name : new GooString("null"));
fontLoc = new GfxFontLoc();
fontLoc->locType = gfxFontLocResident;
fontLoc->fontType = fontType1;
......
......@@ -582,6 +582,10 @@ GlobalParams::GlobalParams(const char *customPopplerDataDir)
psOPI = gFalse;
psASCIIHex = gFalse;
psBinary = gFalse;
psUncompressPreloadedImages = gFalse;
psRasterResolution = 300;
psRasterMono = gFalse;
psAlwaysRasterize = gFalse;
textEncoding = new GooString("UTF-8");
#if defined(_WIN32)
textEOL = eolDOS;
......@@ -596,6 +600,7 @@ GlobalParams::GlobalParams(const char *customPopplerDataDir)
disableFreeTypeHinting = gFalse;
antialias = gTrue;
vectorAntialias = gTrue;
antialiasPrinting = gFalse;
strokeAdjust = gTrue;
screenType = screenUnset;
screenSize = -1;
......@@ -610,7 +615,6 @@ GlobalParams::GlobalParams(const char *customPopplerDataDir)
printCommands = gFalse;
profileCommands = gFalse;
errQuiet = gFalse;
splashResolution = 0.0;
cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
unicodeToUnicodeCache =
......@@ -1559,6 +1563,42 @@ GBool GlobalParams::getPSBinary() {
return binary;
}
GBool GlobalParams::getPSUncompressPreloadedImages() {
GBool ah;
lockGlobalParams;
ah = psUncompressPreloadedImages;
unlockGlobalParams;
return ah;
}
double GlobalParams::getPSRasterResolution() {
double res;
lockGlobalParams;
res = psRasterResolution;
unlockGlobalParams;
return res;
}
GBool GlobalParams::getPSRasterMono() {
GBool mono;
lockGlobalParams;
mono = psRasterMono;
unlockGlobalParams;
return mono;
}
GBool GlobalParams::getPSAlwaysRasterize() {
GBool rast;
lockGlobalParams;
rast = psAlwaysRasterize;
unlockGlobalParams;
return rast;
}
GooString *GlobalParams::getTextEncodingName() {
GooString *s;
......@@ -1631,6 +1671,15 @@ GBool GlobalParams::getVectorAntialias() {
return f;
}
GBool GlobalParams::getAntialiasPrinting() {
GBool f;
lockGlobalParams;
f = antialiasPrinting;
unlockGlobalParams;
return f;
}
GBool GlobalParams::getStrokeAdjust() {
GBool f;
......@@ -1745,14 +1794,6 @@ GBool GlobalParams::getErrQuiet() {
return errQuiet;
}
double GlobalParams::getSplashResolution() {
double r;
lockGlobalParams;
r = splashResolution;
unlockGlobalParams;
return r;
}
CharCodeToUnicode *GlobalParams::getCIDToUnicode(GooString *collection) {
GooString *fileName;
CharCodeToUnicode *ctu;
......@@ -1944,6 +1985,30 @@ void GlobalParams::setPSBinary(GBool binary) {
unlockGlobalParams;
}
void GlobalParams::setPSUncompressPreloadedImages(GBool uncomp) {
lockGlobalParams;
psUncompressPreloadedImages = uncomp;
unlockGlobalParams;
}
void GlobalParams::setPSRasterResolution(double res) {
lockGlobalParams;
psRasterResolution = res;
unlockGlobalParams;
}
void GlobalParams::setPSRasterMono(GBool mono) {
lockGlobalParams;
psRasterMono = mono;
unlockGlobalParams;
}
void GlobalParams::setPSAlwaysRasterize(GBool always) {
lockGlobalParams;
psAlwaysRasterize = always;
unlockGlobalParams;
}
void GlobalParams::setTextEncoding(char *encodingName) {
lockGlobalParams;
delete textEncoding;
......@@ -2015,6 +2080,12 @@ GBool GlobalParams::setVectorAntialias(char *s) {
return ok;
}
void GlobalParams::setAntialiasPrinting(GBool anti) {
lockGlobalParams;
antialiasPrinting = anti;
unlockGlobalParams;
}
void GlobalParams::setStrokeAdjust(GBool adjust)
{
lockGlobalParams;
......@@ -2107,12 +2178,6 @@ void GlobalParams::setErrQuiet(GBool errQuietA) {
unlockGlobalParams;
}
void GlobalParams::setSplashResolution(double SplashResolutionA) {
lockGlobalParams;
splashResolution = SplashResolutionA;
unlockGlobalParams;
}
void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) {
#ifdef ENABLE_PLUGINS
lockGlobalParams;
......
......@@ -165,6 +165,10 @@ public:
GBool getPSOPI();
GBool getPSASCIIHex();
GBool getPSBinary();
GBool getPSUncompressPreloadedImages();
double getPSRasterResolution();
GBool getPSRasterMono();
GBool getPSAlwaysRasterize();
GooString *getTextEncodingName();
EndOfLineKind getTextEOL();
GBool getTextPageBreaks();
......@@ -173,6 +177,7 @@ public:
GBool getDisableFreeTypeHinting();
GBool getAntialias();
GBool getVectorAntialias();
GBool getAntialiasPrinting();
GBool getStrokeAdjust();
ScreenType getScreenType();
int getScreenSize();
......@@ -217,6 +222,10 @@ public:
void setPSOPI(GBool opi);
void setPSASCIIHex(GBool hex);
void setPSBinary(GBool binary);
void setPSUncompressPreloadedImages(GBool uncomp);
void setPSRasterResolution(double res);
void setPSRasterMono(GBool mono);
void setPSAlwaysRasterize(GBool always);
void setTextEncoding(char *encodingName);
GBool setTextEOL(char *s);
void setTextPageBreaks(GBool pageBreaks);
......@@ -225,6 +234,7 @@ public:
GBool setDisableFreeTypeHinting(char *s);
GBool setAntialias(char *s);
GBool setVectorAntialias(char *s);
void setAntialiasPrinting(GBool print);
void setStrokeAdjust(GBool strokeAdjust);
void setScreenType(ScreenType st);
void setScreenSize(int size);
......@@ -239,7 +249,6 @@ public:
void setPrintCommands(GBool printCommandsA);
void setProfileCommands(GBool profileCommandsA);
void setErrQuiet(GBool errQuietA);
void setSplashResolution(double splashResolutionA);
//----- security handlers
......@@ -313,6 +322,12 @@ private:
GBool psOPI; // generate PostScript OPI comments?
GBool psASCIIHex; // use ASCIIHex instead of ASCII85?
GBool psBinary; // use binary instead of hex
GBool psUncompressPreloadedImages; // uncompress all preloaded images
double psRasterResolution; // PostScript rasterization resolution (dpi)
GBool psRasterMono; // true to do PostScript rasterization
// in monochrome (gray); false to do it
// in color (RGB/CMYK)
GBool psAlwaysRasterize; // force PostScript rasterization
GooString *textEncoding; // encoding (unicodeMap) to use for text
// output
EndOfLineKind textEOL; // type of EOL marker to use for text
......@@ -323,6 +338,7 @@ private:
GBool disableFreeTypeHinting; // FreeType disable hinting flag
GBool antialias; // anti-aliasing enable flag
GBool vectorAntialias; // vector anti-aliasing enable flag
GBool antialiasPrinting; // allow anti-aliasing when printing
GBool strokeAdjust; // stroke adjustment enable flag
ScreenType screenType; // halftone screen type
int screenSize; // screen matrix size
......
......@@ -60,9 +60,9 @@ description for all fonts available in Windows. That's how MuPDF works.
#define DEFAULT_SUBSTITUTE_FONT "Helvetica"
static struct {
char *name;
char *t1FileName;
char *ttFileName;
const char *name;
const char *t1FileName;
const char *ttFileName;
} displayFontTab[] = {
{"Courier", "n022003l.pfb", "cour.ttf"},
{"Courier-Bold", "n022004l.pfb", "courbd.ttf"},
......@@ -253,7 +253,8 @@ void SysFontList::scanWindowsFonts(GooString *winFontDir) {
data[dataLen] = '\0';
n = strlen(data);
if (!strcasecmp(data + n - 4, ".ttf") ||
!strcasecmp(data + n - 4, ".ttc")) {
!strcasecmp(data + n - 4, ".ttc") ||
!strcasecmp(data + n - 4, ".otf")) {
fontPath = new GooString(data);
if (!(dataLen >= 3 && data[1] == ':' && data[2] == '\\')) {
fontPath->insert(0, '\\');
......@@ -301,6 +302,11 @@ SysFontInfo *SysFontList::makeWindowsFont(char *name, int fontNum,
n -= 11;
}
// remove trailing ' (OpenType)'
if (n > 11 && !strncmp(name + n - 11, " (OpenType)", 11)) {
n -= 11;
}
// remove trailing ' Italic'
if (n > 7 && !strncmp(name + n - 7, " Italic", 7)) {
n -= 7;
......@@ -401,7 +407,7 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
*fontNum = fi->fontNum;
} else {
GooString *substFontName = new GooString(findSubstituteName(fontName->getCString()));
error(errSyntaxError, -1, "Couldn't find a font for '{0:t}', subst is '{0:s}'", fontName, substFontName);
error(errSyntaxError, -1, "Couldn't find a font for '{0:t}', subst is '{1:t}'", fontName, substFontName);
if ((fi = sysFonts->find(substFontName, gFalse))) {
path = fi->path->copy();
*type = fi->type;
......
......@@ -134,7 +134,7 @@ void Hints::readTables(BaseStream *str, Linearization *linearization, XRef *xref
if (parser->getObj(&obj)->isInt() &&
(num = obj.getInt(), obj.free(), parser->getObj(&obj)->isInt()) &&
(gen = obj.getInt(), obj.free(), parser->getObj(&obj)->isCmd("obj")) &&
(obj.free(), parser->getObj(&obj,
(obj.free(), parser->getObj(&obj, gFalse,
secHdlr ? secHdlr->getFileKey() : (Guchar *)NULL,
secHdlr ? secHdlr->getEncAlgorithm() : cryptRC4,
secHdlr ? secHdlr->getFileKeyLength() : 0,
......
This diff is collapsed.
......@@ -43,16 +43,20 @@
#include "GlobalParams.h"
#include "OutputDev.h"
class GHooash;
class PDFDoc;
class XRef;
class Function;
class GfxPath;
class GfxFont;
class GfxColorSpace;
class GfxSeparationColorSpace;
class PDFRectangle;
struct PST1FontName;
struct PSFont8Info;
struct PSFont16Enc;
class PSOutCustomColor;
class Function;
class PDFDoc;
class PSOutputDev;
//------------------------------------------------------------------------
// PSOutputDev
......@@ -72,8 +76,17 @@ enum PSFileType {
psGeneric // write to a generic stream
};
enum PSOutCustomCodeLocation {
psOutCustomDocSetup,
psOutCustomPageSetup
};
typedef void (*PSOutputFunc)(void *stream, const char *data, int len);
typedef GooString *(*PSOutCustomCodeCbk)(PSOutputDev *psOut,
PSOutCustomCodeLocation loc, int n,
void *data);
class PSOutputDev: public OutputDev {
public:
......@@ -85,8 +98,9 @@ public:
GBool duplexA = gTrue,
int imgLLXA = 0, int imgLLYA = 0,
int imgURXA = 0, int imgURYA = 0,
GBool forceRasterizeA = gFalse,
GBool manualCtrlA = gFalse);
GBool manualCtrlA = gFalse,
PSOutCustomCodeCbk customCodeCbkA = NULL,
void *customCodeCbkDataA = NULL);
// Open a PSOutputDev that will write to a generic stream.
PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA,
......@@ -97,8 +111,9 @@ public:
GBool duplexA = gTrue,
int imgLLXA = 0, int imgLLYA = 0,
int imgURXA = 0, int imgURYA = 0,
GBool forceRasterizeA = gFalse,
GBool manualCtrlA = gFalse);
GBool manualCtrlA = gFalse,
PSOutCustomCodeCbk customCodeCbkA = NULL,
void *customCodeCbkDataA = NULL);
// Destructor -- writes the trailer and closes the file.
virtual ~PSOutputDev();
......@@ -310,7 +325,7 @@ private:
void setupType3Font(GfxFont *font, GooString *psName, Dict *parentResDict);
GooString *makePSFontName(GfxFont *font, Ref *id);
void setupImages(Dict *resDict);
void setupImage(Ref id, Stream *str);
void setupImage(Ref id, Stream *str, GBool mask);
void setupForms(Dict *resDict);
void setupForm(Ref id, Object *strObj);
void addProcessColor(double c, double m, double y, double k);
......@@ -376,6 +391,7 @@ private:
PSOutMode mode; // PostScript mode (PS, EPS, form)
int paperWidth; // width of paper, in pts
int paperHeight; // height of paper, in pts
GBool paperMatch; // true if paper size is set to match each page
int prevWidth; // width of previous page
// (only psModePSOrigPageSizes output mode)
int prevHeight; // height of previous page
......@@ -394,6 +410,10 @@ private:
void *underlayCbkData;
void (*overlayCbk)(PSOutputDev *psOut, void *data);
void *overlayCbkData;
GooString *(*customCodeCbk)(PSOutputDev *psOut,
PSOutCustomCodeLocation loc, int n,
void *data);
void *customCodeCbkData;
PDFDoc *doc;
XRef *xref; // the xref table for this PDF file
......@@ -402,15 +422,9 @@ private:
int fontIDLen; // number of entries in fontIDs array
int fontIDSize; // size of fontIDs array
GooHash *fontNames; // all used font names
Ref *fontFileIDs; // list of object IDs of all embedded fonts
int fontFileIDLen; // number of entries in fontFileIDs array
int fontFileIDSize; // size of fontFileIDs array
GooString **fontFileNames; // list of names of all embedded external fonts
GooString **psFileNames; // list of names of all embedded external fonts
int fontFileNameLen; // number of entries in fontFileNames array
int fontFileNameSize; // size of fontFileNames array
int nextTrueTypeNum; // next unique number to append to a TrueType
// font name
PST1FontName *t1FontNames; // font names for Type 1/1C fonts
int t1FontNameLen; // number of entries in t1FontNames array
int t1FontNameSize; // size of t1FontNames array
PSFont8Info *font8Info; // info for 8-bit fonts
int font8InfoLen; // number of entries in font8Info array
int font8InfoSize; // size of font8Info array
......@@ -429,6 +443,8 @@ private:
int numTilingPatterns; // current number of nested tiling patterns
int nextFunc; // next unique number to use for a function
GooList *paperSizes; // list of used paper sizes, if paperMatch
// is true [PSOutPaperSize]
double tx0, ty0; // global translation
double xScale0, yScale0; // global scaling
int rotate0; // rotation angle (0, 90, 180, 270)
......@@ -453,9 +469,9 @@ private:
GooString *t3String; // Type 3 content string
double t3WX, t3WY, // Type 3 character parameters
t3LLX, t3LLY, t3URX, t3URY;
GBool t3FillColorOnly; // operators should only use the fill color
GBool t3Cacheable; // cleared if char is not cacheable
GBool t3NeedsRestore; // set if a 'q' operator was issued
GBool forceRasterize; // forces the page to be rasterized into a image before printing
GBool displayText; // displayText
#if OPI_SUPPORT
......@@ -465,7 +481,6 @@ private:
GBool ok; // set up ok?
friend class WinPDFPrinter;
};
......
......@@ -59,10 +59,11 @@ Parser::~Parser() {
Object *Parser::getObj(Object *obj, int recursion)
{
return getObj(obj, NULL, cryptRC4, 0, 0, 0, recursion);
return getObj(obj, gFalse, NULL, cryptRC4, 0, 0, 0, recursion);
}
Object *Parser::getObj(Object *obj, Guchar *fileKey,
Object *Parser::getObj(Object *obj, GBool simpleOnly,
Guchar *fileKey,
CryptAlgorithm encAlgorithm, int keyLength,
int objNum, int objGen, int recursion) {
char *key;
......@@ -83,18 +84,18 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey,
}
// array
if (likely(recursion < recursionLimit) && buf1.isCmd("[")) {
if (!simpleOnly && likely(recursion < recursionLimit) && buf1.isCmd("[")) {
shift();
obj->initArray(xref);
while (!buf1.isCmd("]") && !buf1.isEOF())
obj->arrayAdd(getObj(&obj2, fileKey, encAlgorithm, keyLength,
obj->arrayAdd(getObj(&obj2, gFalse, fileKey, encAlgorithm, keyLength,
objNum, objGen, recursion + 1));
if (buf1.isEOF())
error(errSyntaxError, getPos(), "End of file inside array");
shift();
// dictionary or stream
} else if (likely(recursion < recursionLimit) && buf1.isCmd("<<")) {
} else if (!simpleOnly && likely(recursion < recursionLimit) && buf1.isCmd("<<")) {
shift(objNum);
obj->initDict(xref);
while (!buf1.isCmd(">>") && !buf1.isEOF()) {
......@@ -109,7 +110,7 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey,
gfree(key);
break;
}
obj->dictAdd(key, getObj(&obj2, fileKey, encAlgorithm, keyLength, objNum, objGen, recursion + 1));
obj->dictAdd(key, getObj(&obj2, gFalse, fileKey, encAlgorithm, keyLength, objNum, objGen, recursion + 1));
}
}
if (buf1.isEOF())
......
......@@ -42,8 +42,11 @@ public:
// Destructor.
~Parser();
// Get the next object from the input stream.
Object *getObj(Object *obj, Guchar *fileKey = NULL,
// Get the next object from the input stream. If <simpleOnly> is
// true, do not parse compound objects (arrays, dictionaries, or
// streams).
Object *getObj(Object *obj, GBool simpleOnly = gFalse,
Guchar *fileKey = NULL,
CryptAlgorithm encAlgorithm = cryptRC4, int keyLength = 0,
int objNum = 0, int objGen = 0, int recursion = 0);
......
......@@ -95,6 +95,46 @@ GBool PreScanOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *ca
return gTrue;
}
GBool PreScanOutputDev::functionShadedFill(GfxState *state,
GfxFunctionShading *shading) {
if (shading->getColorSpace()->getMode() != csDeviceGray &&
shading->getColorSpace()->getMode() != csCalGray) {
gray = gFalse;
}
mono = gFalse;
if (state->getFillOpacity() != 1 ||
state->getBlendMode() != gfxBlendNormal) {
transparency = gTrue;
}
return gTrue;
}
GBool PreScanOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double /*tMin*/, double /*tMax*/) {
if (shading->getColorSpace()->getMode() != csDeviceGray &&
shading->getColorSpace()->getMode() != csCalGray) {
gray = gFalse;
}
mono = gFalse;
if (state->getFillOpacity() != 1 ||
state->getBlendMode() != gfxBlendNormal) {
transparency = gTrue;
}
return gTrue;
}
GBool PreScanOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading, double /*sMin*/, double /*sMax*/) {
if (shading->getColorSpace()->getMode() != csDeviceGray &&
shading->getColorSpace()->getMode() != csCalGray) {
gray = gFalse;
}
mono = gFalse;
if (state->getFillOpacity() != 1 ||
state->getBlendMode() != gfxBlendNormal) {
transparency = gTrue;
}
return gTrue;
}
void PreScanOutputDev::clip(GfxState * /*state*/) {
//~ check for a rectangle "near" the edge of the page;
//~ else set gdi to false
......@@ -161,7 +201,7 @@ void PreScanOutputDev::drawImageMask(GfxState *state, Object * /*ref*/, Stream *
gdi = gFalse;
if ((level == psLevel1 || level == psLevel1Sep) &&
state->getFillColorSpace()->getMode() == csPattern) {
level1PSBug = gTrue;
patternImgMask = gTrue;
}
if (inlineImg) {
......@@ -184,12 +224,17 @@ void PreScanOutputDev::drawImage(GfxState *state, Object * /*ref*/, Stream *str,
if (colorSpace->getMode() == csIndexed) {
colorSpace = ((GfxIndexedColorSpace *)colorSpace)->getBase();
}
if (colorSpace->getMode() != csDeviceGray &&
colorSpace->getMode() != csCalGray) {
gray = gFalse;
if (colorSpace->getMode() == csDeviceGray ||
colorSpace->getMode() == csCalGray) {
if (colorMap->getBits() > 1) {
mono = gFalse;
}
} else {
gray = gFalse;
mono = gFalse;
if (state->getBlendMode() != gfxBlendNormal) {
}
if (state->getFillOpacity() != 1 ||
state->getBlendMode() != gfxBlendNormal) {
transparency = gTrue;
}
gdi = gFalse;
......@@ -218,12 +263,17 @@ void PreScanOutputDev::drawMaskedImage(GfxState *state, Object * /*ref*/,
if (colorSpace->getMode() == csIndexed) {
colorSpace = ((GfxIndexedColorSpace *)colorSpace)->getBase();
}
if (colorSpace->getMode() != csDeviceGray &&
colorSpace->getMode() != csCalGray) {
gray = gFalse;
if (colorSpace->getMode() == csDeviceGray ||
colorSpace->getMode() == csCalGray) {
if (colorMap->getBits() > 1) {
mono = gFalse;
}
} else {
gray = gFalse;
mono = gFalse;
if (state->getBlendMode() != gfxBlendNormal) {
}
if (state->getFillOpacity() != 1 ||
state->getBlendMode() != gfxBlendNormal) {
transparency = gTrue;
}
gdi = gFalse;
......@@ -303,5 +353,5 @@ void PreScanOutputDev::clearStats() {
gray = gTrue;
transparency = gFalse;
gdi = gTrue;
level1PSBug = gFalse;
patternImgMask = gFalse;
}
......@@ -64,6 +64,11 @@ public:
// operations.
virtual GBool useTilingPatternFill() { return gTrue; }
// Does this device use functionShadedFill(), axialShadedFill(), and
// radialShadedFill()? If this returns false, these shaded fills
// will be reduced to a series of other drawing operations.
virtual GBool useShadedFills(int type) { return gTrue; }
// Does this device use beginType3Char/endType3Char? Otherwise,
// text in Type 3 fonts will be drawn with drawChar/drawString.
virtual GBool interpretType3Chars() { return gTrue; }
......@@ -85,6 +90,10 @@ public:
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep);
virtual GBool functionShadedFill(GfxState *state,
GfxFunctionShading *shading);
virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax);
virtual GBool radialShadedFill(GfxState *state, GfxRadialShading *shading, double tMin, double tMax);
//----- path clipping
virtual void clip(GfxState *state);
......@@ -148,8 +157,9 @@ public:
GBool isAllGDI() { return gdi; }
// Returns true if the operations performed since the last call to
// clearStats() processed a feature that PSOutputDev does not implement.
GBool hasLevel1PSBug() { return level1PSBug; }
// clearStats() included any image mask fills with a pattern color
// space. (only level1!)
GBool usesPatternImageMask() { return patternImgMask; }
// Clear the stats used by the above functions.
void clearStats();
......@@ -165,7 +175,7 @@ private:
GBool transparency;
GBool gdi;
PSLevel level; // PostScript level (1, 2, separation)
GBool level1PSBug; // gTrue if it uses a feature not supported in PSOutputDev
GBool patternImgMask;
};
#endif
......@@ -260,6 +260,7 @@ void XRef::init() {
entries = NULL;
capacity = 0;
size = 0;
last = -1;
streamEnds = NULL;
streamEndsLen = 0;
objStrs = new PopplerCache(5);
......@@ -430,7 +431,7 @@ GBool XRef::readXRef(Guint *pos, std::vector<Guint> *followedXRefStm) {
new Lexer(NULL,
str->makeSubStream(start + *pos, gFalse, 0, &obj)),
gTrue);
parser->getObj(&obj);
parser->getObj(&obj, gTrue);
// parse an old-style xref table
if (obj.isCmd("xref")) {
......@@ -440,11 +441,11 @@ GBool XRef::readXRef(Guint *pos, std::vector<Guint> *followedXRefStm) {
// parse an xref stream
} else if (obj.isInt()) {
obj.free();
if (!parser->getObj(&obj)->isInt()) {
if (!parser->getObj(&obj, gTrue)->isInt()) {
goto err1;
}
obj.free();
if (!parser->getObj(&obj)->isCmd("obj")) {
if (!parser->getObj(&obj, gTrue)->isCmd("obj")) {
goto err1;
}
obj.free();
......@@ -479,7 +480,7 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector<Guint> *follow
int first, n, i;
while (1) {
parser->getObj(&obj);
parser->getObj(&obj, gTrue);
if (obj.isCmd("trailer")) {
obj.free();
break;
......@@ -489,7 +490,7 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector<Guint> *follow
}
first = obj.getInt();
obj.free();
if (!parser->getObj(&obj)->isInt()) {
if (!parser->getObj(&obj, gTrue)->isInt()) {
goto err1;
}
n = obj.getInt();
......@@ -504,19 +505,19 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector<Guint> *follow
}
}
for (i = first; i < first + n; ++i) {
if (!parser->getObj(&obj)->isInt()) {
if (!parser->getObj(&obj, gTrue)->isInt()) {
goto err1;
}
entry.offset = (Guint)obj.getInt();
obj.free();
if (!parser->getObj(&obj)->isInt()) {
if (!parser->getObj(&obj, gTrue)->isInt()) {
goto err1;
}
entry.gen = obj.getInt();
entry.obj.initNull ();
entry.updated = false;
obj.free();
parser->getObj(&obj);
parser->getObj(&obj, gTrue);
if (obj.isCmd("n")) {
entry.type = xrefEntryUncompressed;
} else if (obj.isCmd("f")) {
......@@ -537,6 +538,9 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector<Guint> *follow
entries[0] = entries[1];
entries[1].offset = 0xffffffff;
}
if (i > last) {
last = i;
}
}
}
}
......@@ -549,13 +553,25 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector<Guint> *follow
// get the 'Prev' pointer
obj.getDict()->lookupNF("Prev", &obj2);
if (obj2.isInt()) {
*pos = (Guint)obj2.getInt();
pos2 = (Guint)obj2.getInt();
if (pos2 != *pos) {
*pos = pos2;
more = gTrue;
} else {
error(errSyntaxWarning, -1, "Infinite loop in xref table");
more = gFalse;
}
} else if (obj2.isRef()) {
// certain buggy PDF generators generate "/Prev NNN 0 R" instead
// of "/Prev NNN"
*pos = (Guint)obj2.getRefNum();
pos2 = (Guint)obj2.getRefNum();
if (pos2 != *pos) {
*pos = pos2;
more = gTrue;
} else {
error(errSyntaxWarning, -1, "Infinite loop in xref table");
more = gFalse;