lib/pdf: make startPage() upstream compatible
[swftools.git] / lib / pdf / xpdf-changes.patch
1 --- xpdf/Catalog.cc.orig        2010-05-18 11:22:18.000000000 -0700
2 +++ xpdf/Catalog.cc     2010-05-18 11:22:18.000000000 -0700
3 @@ -193,7 +193,7 @@
4    if (!kids.isArray()) {
5      error(-1, "Kids object (page %d) is wrong type (%s)",
6           start+1, kids.getTypeName());
7 -    goto err1;
8 +    return start;
9    }
10    for (i = 0; i < kids.arrayGetLength(); ++i) {
11      kids.arrayGetNF(i, &kidRef);
12 --- xpdf/CharCodeToUnicode.cc.orig      2010-05-18 11:22:18.000000000 -0700
13 +++ xpdf/CharCodeToUnicode.cc   2010-05-18 11:22:18.000000000 -0700
14 @@ -208,13 +208,13 @@
15                                    int nBits) {
16    PSTokenizer *pst;
17    char tok1[256], tok2[256], tok3[256];
18 -  int nDigits, n1, n2, n3;
19 +  int maxCode, n1, n2, n3;
20    CharCode i;
21    CharCode code1, code2;
22    GString *name;
23    FILE *f;
24  
25 -  nDigits = nBits / 4;
26 +  maxCode = (nBits == 8) ? 0xff : (nBits == 16) ? 0xffff : 0xffffffff;
27    pst = new PSTokenizer(getCharFunc, data);
28    pst->getToken(tok1, sizeof(tok1), &n1);
29    while (pst->getToken(tok2, sizeof(tok2), &n2)) {
30 @@ -241,9 +241,9 @@
31           error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
32           break;
33         }
34 -       if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
35 +       if (!(tok1[0] == '<' && tok1[n1 - 1] == '>' &&
36               tok2[0] == '<' && tok2[n2 - 1] == '>')) {
37 -         error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
38 +         error(-1, "Illegal entry in bfchar block in ToUnicode CMap.");
39           continue;
40         }
41         tok1[n1 - 1] = tok2[n2 - 1] = '\0';
42 @@ -251,6 +251,9 @@
43           error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
44           continue;
45         }
46 +        if (code1 > maxCode) {
47 +          error(-1, "Invalid entry in bfchar block in ToUnicode CMap");
48 +        }
49         addMapping(code1, tok2 + 1, n2 - 2, 0);
50        }
51        pst->getToken(tok1, sizeof(tok1), &n1);
52 @@ -266,8 +269,8 @@
53           error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
54           break;
55         }
56 -       if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
57 -             n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) {
58 +       if (!(tok1[0] == '<' && tok1[n1 - 1] == '>' &&
59 +             tok2[0] == '<' && tok2[n2 - 1] == '>')) {
60           error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
61           continue;
62         }
63 @@ -277,6 +280,10 @@
64           error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
65           continue;
66         }
67 +        if (code1 > maxCode || code2 > maxCode) {
68 +           error(-1, "Invalid entry in bfrange block in ToUnicode CMap");
69 +       }
70 +
71         if (!strcmp(tok3, "[")) {
72           i = 0;
73           while (pst->getToken(tok1, sizeof(tok1), &n1) &&
74 @@ -320,7 +327,13 @@
75    if (code >= mapLen) {
76      oldLen = mapLen;
77      mapLen = (code + 256) & ~255;
78 +    Unicode *oldmap;
79      map = (Unicode *)greallocn(map, mapLen, sizeof(Unicode));
80 +    if(!map) {
81 +       /* we sometimes get overflows for files trying to use 0xffffffff as charcode */
82 +       map = oldmap;
83 +       return;
84 +    }
85      for (i = oldLen; i < mapLen; ++i) {
86        map[i] = 0;
87      }
88 --- xpdf/Decrypt.cc.orig        2010-05-18 11:22:18.000000000 -0700
89 +++ xpdf/Decrypt.cc     2010-05-18 11:22:18.000000000 -0700
90 @@ -596,6 +596,7 @@
91    s->bufIdx = 0;
92    if (last) {
93      n = s->buf[15];
94 +    if(!n || n>16) n=16;
95      for (i = 15; i >= n; --i) {
96        s->buf[i] = s->buf[i-n];
97      }
98 --- xpdf/Gfx.cc.orig    2010-05-18 11:22:18.000000000 -0700
99 +++ xpdf/Gfx.cc 2010-05-18 11:22:18.000000000 -0700
100 @@ -465,6 +469,7 @@
101    abortCheckCbkData = abortCheckCbkDataA;
102  
103    // set crop box
104 +#ifdef XPDFEXE
105    if (cropBox) {
106      state->moveTo(cropBox->x1, cropBox->y1);
107      state->lineTo(cropBox->x2, cropBox->y1);
108 @@ -475,6 +480,7 @@
109      out->clip(state);
110      state->clearPath();
111    }
112 +#endif
113  }
114  
115  Gfx::Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict,
116 @@ -3182,8 +3188,11 @@
117                             u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
118                             &dx, &dy, &originX, &originY);
119        dx = dx * state->getFontSize() + state->getCharSpace();
120 -      if (n == 1 && *p == ' ') {
121 -       dx += state->getWordSpace();
122 +      if (n == 1 && (*p == ' ' || *p == 0)) {
123 +        double w=state->getWordSpace();
124 +        if (w==0 && dx==0)
125 +          w=state->getFontSize()/3; // workaround for zero word space
126 +        dx += w;
127        }
128        dx *= state->getHorizScaling();
129        dy *= state->getFontSize();
130 @@ -3476,11 +3485,13 @@
131        }
132      }
133      if (!obj1.isNull()) {
134 -      colorSpace = GfxColorSpace::parse(&obj1);
135 +      colorSpace = GfxColorSpace::parse(&obj1, csMode);
136      } else if (csMode == streamCSDeviceGray) {
137        colorSpace = new GfxDeviceGrayColorSpace();
138      } else if (csMode == streamCSDeviceRGB) {
139        colorSpace = new GfxDeviceRGBColorSpace();
140 +    } else if (csMode == streamCSDeviceRGBX) {
141 +      colorSpace = new GfxDeviceRGBXColorSpace();
142      } else if (csMode == streamCSDeviceCMYK) {
143        colorSpace = new GfxDeviceCMYKColorSpace();
144      } else {
145 @@ -3824,6 +3835,7 @@
146      out->beginTransparencyGroup(state, bbox, blendingColorSpace,
147                                 isolated, knockout, softMask);
148    }
149 +  GfxState*old_state = state;
150  
151    // set new base matrix
152    for (i = 0; i < 6; ++i) {
153 @@ -3835,6 +3847,9 @@
154    display(str, gFalse);
155  
156    if (softMask || transpGroup) {
157 +    // restore graphics state
158 +    while(state != old_state)
159 +       restoreState();
160      out->endTransparencyGroup(state);
161    }
162  
163 --- xpdf/GfxFont.cc.orig        2010-05-18 11:22:18.000000000 -0700
164 +++ xpdf/GfxFont.cc     2010-05-18 11:22:18.000000000 -0700
165 @@ -194,7 +194,7 @@
166        embFontID = obj2.getRef();
167        if (type != fontType1) {
168         error(-1, "Mismatch between font type and embedded font file");
169 -       type = fontType1;
170 +       type = isCIDFont() ? fontCIDType0 : fontType1;
171        }
172      }
173      obj2.free();
174 @@ -919,6 +919,10 @@
175    return 1;
176  }
177  
178 +CharCodeToUnicode* Gfx8BitFont::getCTU() {
179 +    return ctu;
180 +}
181 +
182  CharCodeToUnicode *Gfx8BitFont::getToUnicode() {
183    ctu->incRefCnt();
184    return ctu;
185 @@ -1411,6 +1415,10 @@
186    }
187  }
188  
189 +CharCodeToUnicode* GfxCIDFont::getCTU() {
190 +    return ctu;
191 +}
192 +
193  int GfxCIDFont::getNextChar(char *s, int len, CharCode *code,
194                             Unicode *u, int uSize, int *uLen,
195                             double *dx, double *dy, double *ox, double *oy) {
196 --- xpdf/GfxFont.h.orig 2010-05-18 11:22:18.000000000 -0700
197 +++ xpdf/GfxFont.h      2010-05-18 11:22:18.000000000 -0700
198 @@ -164,6 +164,7 @@
199    virtual int getNextChar(char *s, int len, CharCode *code,
200                           Unicode *u, int uSize, int *uLen,
201                           double *dx, double *dy, double *ox, double *oy) = 0;
202 +  virtual CharCodeToUnicode* getCTU() = 0;
203  
204  protected:
205  
206 @@ -204,6 +205,7 @@
207    virtual int getNextChar(char *s, int len, CharCode *code,
208                           Unicode *u, int uSize, int *uLen,
209                           double *dx, double *dy, double *ox, double *oy);
210 +  virtual CharCodeToUnicode* getCTU();
211  
212    // Return the encoding.
213    char **getEncoding() { return enc; }
214 @@ -212,7 +214,7 @@
215    CharCodeToUnicode *getToUnicode();
216  
217    // Return the character name associated with <code>.
218 -  char *getCharName(int code) { return enc[code]; }
219 +  char *getCharName(int code) { return code>=256?0:enc[code]; }
220  
221    // Returns true if the PDF font specified an encoding.
222    GBool getHasEncoding() { return hasEncoding; }
223 @@ -266,6 +268,7 @@
224    virtual int getNextChar(char *s, int len, CharCode *code,
225                           Unicode *u, int uSize, int *uLen,
226                           double *dx, double *dy, double *ox, double *oy);
227 +  virtual CharCodeToUnicode* getCTU();
228  
229    // Return the writing mode (0=horizontal, 1=vertical).
230    virtual int getWMode();
231 --- xpdf/GfxState.cc.orig       2010-05-18 11:22:18.000000000 -0700
232 +++ xpdf/GfxState.cc    2010-05-18 11:22:18.000000000 -0700
233 @@ -21,6 +21,7 @@
234  #include "Array.h"
235  #include "Page.h"
236  #include "GfxState.h"
237 +#include "cmyk.h"
238  
239  //------------------------------------------------------------------------
240  
241 @@ -92,7 +93,7 @@
242  GfxColorSpace::~GfxColorSpace() {
243  }
244  
245 -GfxColorSpace *GfxColorSpace::parse(Object *csObj) {
246 +GfxColorSpace *GfxColorSpace::parse(Object *csObj, StreamColorSpaceMode csMode) {
247    GfxColorSpace *cs;
248    Object obj1;
249  
250 @@ -101,7 +102,10 @@
251      if (csObj->isName("DeviceGray") || csObj->isName("G")) {
252        cs = new GfxDeviceGrayColorSpace();
253      } else if (csObj->isName("DeviceRGB") || csObj->isName("RGB")) {
254 -      cs = new GfxDeviceRGBColorSpace();
255 +      if(csMode == streamCSDeviceRGBX)
256 +       cs = new GfxDeviceRGBXColorSpace();
257 +      else
258 +       cs = new GfxDeviceRGBColorSpace();
259      } else if (csObj->isName("DeviceCMYK") || csObj->isName("CMYK")) {
260        cs = new GfxDeviceCMYKColorSpace();
261      } else if (csObj->isName("Pattern")) {
262 @@ -114,7 +118,10 @@
263      if (obj1.isName("DeviceGray") || obj1.isName("G")) {
264        cs = new GfxDeviceGrayColorSpace();
265      } else if (obj1.isName("DeviceRGB") || obj1.isName("RGB")) {
266 -      cs = new GfxDeviceRGBColorSpace();
267 +      if(csMode == streamCSDeviceRGBX)
268 +        cs = new GfxDeviceRGBColorSpace();
269 +      else
270 +       cs = new GfxDeviceRGBColorSpace();
271      } else if (obj1.isName("DeviceCMYK") || obj1.isName("CMYK")) {
272        cs = new GfxDeviceCMYKColorSpace();
273      } else if (obj1.isName("CalGray")) {
274 @@ -333,6 +340,17 @@
275  }
276  
277  //------------------------------------------------------------------------
278 +// GfxDeviceRGBXColorSpace
279 +//------------------------------------------------------------------------
280 +
281 +GfxDeviceRGBXColorSpace::GfxDeviceRGBXColorSpace() {
282 +}
283 +
284 +GfxColorSpace *GfxDeviceRGBXColorSpace::copy() {
285 +  return new GfxDeviceRGBXColorSpace();
286 +}
287 +
288 +//------------------------------------------------------------------------
289  // GfxCalRGBColorSpace
290  //------------------------------------------------------------------------
291  
292 @@ -490,6 +508,18 @@
293                                 - 0.11 * color->c[2] + 0.5));
294  }
295  
296 +/*void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
297 +    unsigned char r,g,b;
298 +    float c = color->c[0];
299 +    float m = color->c[1];
300 +    float y = color->c[2];
301 +    float k = color->c[3];
302 +    convert_cmyk2rgb(c,m,y,k, &r,&g,&b);
303 +    rgb->r = r/255.0;
304 +    rgb->g = g/255.0;
305 +    rgb->b = b/255.0;
306 +}*/
307 +
308  void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
309    double c, m, y, k, c1, m1, y1, k1, r, g, b, x;
310  
311 @@ -3187,6 +3217,7 @@
312    GfxIndexedColorSpace *indexedCS;
313    GfxSeparationColorSpace *sepCS;
314    int maxPixel, indexHigh;
315 +  int maxPixelForAlloc;
316    Guchar *lookup2;
317    Function *sepFunc;
318    Object obj;
319 @@ -3199,6 +3230,7 @@
320    // bits per component and color space
321    bits = bitsA;
322    maxPixel = (1 << bits) - 1;
323 +  maxPixelForAlloc = (1 << (bits>8?bits:8));
324    colorSpace = colorSpaceA;
325  
326    // initialize
327 @@ -3253,7 +3285,7 @@
328      lookup2 = indexedCS->getLookup();
329      colorSpace2->getDefaultRanges(x, y, indexHigh);
330      for (k = 0; k < nComps2; ++k) {
331 -      lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
332 +      lookup[k] = (GfxColorComp *)gmallocn(maxPixelForAlloc + 1,
333                                            sizeof(GfxColorComp));
334        for (i = 0; i <= maxPixel; ++i) {
335         j = (int)(decodeLow[0] + (i * decodeRange[0]) / maxPixel + 0.5);
336 @@ -3272,7 +3304,7 @@
337      nComps2 = colorSpace2->getNComps();
338      sepFunc = sepCS->getFunc();
339      for (k = 0; k < nComps2; ++k) {
340 -      lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
341 +      lookup[k] = (GfxColorComp *)gmallocn(maxPixelForAlloc + 1,
342                                            sizeof(GfxColorComp));
343        for (i = 0; i <= maxPixel; ++i) {
344         x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel;
345 @@ -3282,7 +3314,7 @@
346      }
347    } else {
348      for (k = 0; k < nComps; ++k) {
349 -      lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
350 +      lookup[k] = (GfxColorComp *)gmallocn(maxPixelForAlloc + 1,
351                                            sizeof(GfxColorComp));
352        for (i = 0; i <= maxPixel; ++i) {
353         lookup[k][i] = dblToCol(decodeLow[k] +
354 @@ -3754,7 +3786,10 @@
355  }
356  
357  void GfxState::setPath(GfxPath *pathA) {
358 +  if(pathA) {
359 +      if(path)
360    delete path;
361 +  }
362    path = pathA;
363  }
364  
365 --- xpdf/GfxState.h.orig        2010-05-18 11:22:18.000000000 -0700
366 +++ xpdf/GfxState.h     2010-05-18 11:22:18.000000000 -0700
367 @@ -138,7 +138,7 @@
368    virtual GfxColorSpaceMode getMode() = 0;
369  
370    // Construct a color space.  Returns NULL if unsuccessful.
371 -  static GfxColorSpace *parse(Object *csObj);
372 +  static GfxColorSpace *parse(Object *csObj, StreamColorSpaceMode csMode = streamCSNone);
373  
374    // Convert to gray, RGB, or CMYK.
375    virtual void getGray(GfxColor *color, GfxGray *gray) = 0;
376 @@ -252,6 +252,19 @@
377  };
378  
379  //------------------------------------------------------------------------
380 +// GfxDeviceRGBXColorSpace
381 +//------------------------------------------------------------------------
382 +
383 +class GfxDeviceRGBXColorSpace: public GfxDeviceRGBColorSpace {
384 +public:
385 +
386 +  GfxDeviceRGBXColorSpace();
387 +  virtual GfxColorSpace *copy();
388 +  virtual int getNComps() { return 4; }
389 +private:
390 +};
391 +
392 +//------------------------------------------------------------------------
393  // GfxCalRGBColorSpace
394  //------------------------------------------------------------------------
395  
396 --- xpdf/GlobalParams.cc.orig   2010-05-18 11:22:18.000000000 -0700
397 +++ xpdf/GlobalParams.cc        2010-05-18 11:22:18.000000000 -0700
398 @@ -914,6 +914,29 @@
399    int line;
400    char buf[512];
401  
402 +  /* extract path */
403 +  if(fileName) {
404 +    char* cfgFileName = fileName->getCString();
405 +    char* pos1 = strrchr(cfgFileName, '/');
406 +    char* pos2 = strrchr(cfgFileName, '\\');
407 +    char* p = pos1>pos2?pos1:pos2;
408 +    int pos = p ? p-cfgFileName : -1;
409 +    GString*path = new GString(new GString(cfgFileName), 0, (pos < 0 ? strlen(cfgFileName): pos));
410 +    if(pos1>=0)
411 +       path->append('/');
412 +    else if(pos2>=0)
413 +       path->append('\\');
414 +    else
415 +#ifdef WIN32
416 +       path->append('\\');
417 +#else
418 +       path->append('/');
419 +#endif
420 +    this->path = path;
421 +  } else {
422 +    this->path = new GString();
423 +  }
424 +  
425    line = 1;
426    while (getLine(buf, sizeof(buf) - 1, f)) {
427      parseLine(buf, fileName, line);
428 @@ -1114,6 +1137,42 @@
429    deleteGList(tokens, GString);
430  }
431  
432 +static char is_absolute(char*filename)
433 +{
434 +    int l = strlen(filename);
435 +    if(filename[0] == '/' || filename[0] == '\\') 
436 +       return 1;
437 +    if(l>2 && filename[1]==':' && (filename[2]=='\\' || filename[2]=='/'))
438 +       return 1;
439 +    return 0;
440 +}
441 +
442 +static GString* qualify_filename(GString*path, GString*filename)
443 +{
444 +  GString*fullpath = 0;
445 +  char*prefix = "/usr/local/share/xpdf/";
446 +
447 +  if (!is_absolute(filename->getCString())) {
448 +    /* relative path */
449 +    fullpath = path->copy();
450 +    fullpath->append(filename);
451 +  } else if (!strncmp(filename->getCString(), prefix, strlen(prefix))) {
452 +    /* xpdf default path */
453 +    char*s = strchr(filename->getCString()+strlen(prefix), '/');
454 +    if(s) {
455 +       fullpath = path->copy();
456 +       fullpath->append(s+1);
457 +    } else {
458 +       fullpath = filename->copy();
459 +    }
460 +  } else {
461 +    /* absolute path */
462 +    fullpath = filename->copy();
463 +  }
464 +  //printf("%s -%s-> %s\n", filename->getCString(), path->getCString(), fullpath->getCString());
465 +  return fullpath;
466 +}
467 +
468  void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName,
469                                          int line) {
470    GString *name;
471 @@ -1128,10 +1187,10 @@
472           fileName->getCString(), line);
473      return;
474    }
475 -  name = (GString *)tokens->get(1);
476 +  name = qualify_filename(this->path, (GString *)tokens->get(1));
477    if (!(f = fopen(name->getCString(), "r"))) {
478 -    error(-1, "Couldn't open 'nameToUnicode' file '%s'",
479 -         name->getCString());
480 +    error(-1, "Couldn't open 'nameToUnicode' file '%s' using path '%s'",
481 +         name->getCString(), path->getCString());
482      return;
483    }
484    line2 = 1;
485 @@ -1160,10 +1219,12 @@
486    }
487    collection = (GString *)tokens->get(1);
488    name = (GString *)tokens->get(2);
489 +
490    if ((old = (GString *)cidToUnicodes->remove(collection))) {
491      delete old;
492    }
493 -  cidToUnicodes->add(collection->copy(), name->copy());
494 +
495 +  cidToUnicodes->add(collection->copy(), qualify_filename(this->path, name));
496  }
497  
498  void GlobalParams::parseUnicodeToUnicode(GList *tokens, GString *fileName,
499 @@ -1180,7 +1241,8 @@
500    if ((old = (GString *)unicodeToUnicodes->remove(font))) {
501      delete old;
502    }
503 -  unicodeToUnicodes->add(font->copy(), file->copy());
504 +
505 +  unicodeToUnicodes->add(font->copy(), qualify_filename(this->path, file));
506  }
507  
508  void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName,
509 @@ -1197,7 +1259,8 @@
510    if ((old = (GString *)unicodeMaps->remove(encodingName))) {
511      delete old;
512    }
513 -  unicodeMaps->add(encodingName->copy(), name->copy());
514 +
515 +  unicodeMaps->add(encodingName->copy(), qualify_filename(this->path, name));
516  }
517  
518  void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) {
519 @@ -1215,23 +1278,30 @@
520      list = new GList();
521      cMapDirs->add(collection->copy(), list);
522    }
523 -  list->append(dir->copy());
524 +
525 +  list->append(qualify_filename(this->path, dir));
526  }
527  
528  void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
529                                      int line) {
530 +  GString *dir;
531 +
532    if (tokens->getLength() != 2) {
533      error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
534           fileName->getCString(), line);
535      return;
536    }
537 -  toUnicodeDirs->append(((GString *)tokens->get(1))->copy());
538 +
539 +  dir = (GString *)tokens->get(1);
540 +
541 +  toUnicodeDirs->append(qualify_filename(this->path, dir));
542  }
543  
544  void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash,
545                                     DisplayFontParamKind kind,
546                                     GString *fileName, int line) {
547    DisplayFontParam *param, *old;
548 +  GString *file;
549  
550    if (tokens->getLength() < 2) {
551      goto err1;
552 @@ -1243,13 +1313,15 @@
553      if (tokens->getLength() != 3) {
554        goto err2;
555      }
556 -    param->t1.fileName = ((GString *)tokens->get(2))->copy();
557 +    file = (GString *)tokens->get(2);
558 +    param->t1.fileName = qualify_filename(this->path, file);
559      break;
560    case displayFontTT:
561      if (tokens->getLength() != 3) {
562        goto err2;
563      }
564 -    param->tt.fileName = ((GString *)tokens->get(2))->copy();
565 +    file = (GString *)tokens->get(2);
566 +    param->tt.fileName = qualify_filename(this->path, file);
567      break;
568    }
569  
570 --- xpdf/GlobalParams.h.orig    2010-05-18 11:22:18.000000000 -0700
571 +++ xpdf/GlobalParams.h 2010-05-18 11:22:18.000000000 -0700
572 @@ -196,7 +196,7 @@
573    // file.
574    GlobalParams(char *cfgFileName);
575  
576 -  ~GlobalParams();
577 +  virtual ~GlobalParams();
578  
579    void setBaseDir(char *dir);
580    void setupBaseFonts(char *dir);
581 @@ -213,8 +213,8 @@
582    FILE *getUnicodeMapFile(GString *encodingName);
583    FILE *findCMapFile(GString *collection, GString *cMapName);
584    FILE *findToUnicodeFile(GString *name);
585 -  DisplayFontParam *getDisplayFont(GString *fontName);
586 -  DisplayFontParam *getDisplayCIDFont(GString *fontName, GString *collection);
587 +  virtual DisplayFontParam *getDisplayFont(GString *fontName);
588 +  virtual DisplayFontParam *getDisplayCIDFont(GString *fontName, GString *collection);
589    GString *getPSFile();
590    int getPSPaperWidth();
591    int getPSPaperHeight();
592 @@ -316,7 +316,7 @@
593  private:
594  
595    void createDefaultKeyBindings();
596 -  void parseFile(GString *fileName, FILE *f);
597 +public: void parseFile(GString *fileName, FILE *f); private:
598    void parseNameToUnicode(GList *tokens, GString *fileName, int line);
599    void parseCIDToUnicode(GList *tokens, GString *fileName, int line);
600    void parseUnicodeToUnicode(GList *tokens, GString *fileName, int line);
601 @@ -358,6 +358,10 @@
602    GBool loadPlugin(char *type, char *name);
603  #endif
604  
605 +  //----- config file base path
606 +
607 +  GString*path;
608 +
609    //----- static tables
610  
611    NameToCharCode *             // mapping from char name to
612 --- xpdf/JBIG2Stream.cc.orig    2010-05-18 11:22:18.000000000 -0700
613 +++ xpdf/JBIG2Stream.cc 2010-05-18 11:22:18.000000000 -0700
614 @@ -1514,11 +1514,14 @@
615    }
616  
617    // compute symbol code length
618 -  symCodeLen = 1;
619 -  i = (numInputSyms + numNewSyms) >> 1;
620 -  while (i) {
621 -    ++symCodeLen;
622 -    i >>= 1;
623 +  symCodeLen = 0;
624 +  i = 1;
625 +  while (i < numInputSyms + numNewSyms) {
626 +   ++symCodeLen;
627 +   i <<= 1;
628 +  }
629 +  if (huff && symCodeLen == 0) {
630 +   symCodeLen = 1;
631    }
632  
633    // get the input symbol bitmaps
634 @@ -1921,6 +1924,9 @@
635      ++symCodeLen;
636      i <<= 1;
637    }
638 +  if (huff && symCodeLen == 0) {
639 +    symCodeLen = 1;
640 +  }
641  
642    // get the symbol bitmaps
643    syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *));
644 --- xpdf/JPXStream.cc.orig      2010-05-18 11:22:18.000000000 -0700
645 +++ xpdf/JPXStream.cc   2010-05-18 11:22:18.000000000 -0700
646 @@ -241,6 +242,12 @@
647    haveCompMap = gFalse;
648    haveChannelDefn = gFalse;
649  
650 +  img.xSize = 0;
651 +  img.ySize = 0;
652 +  img.xOffset = 0;
653 +  img.yOffset = 0;
654 +  curX = 0;
655 +  curY = 0;
656    img.tiles = NULL;
657    bitBuf = 0;
658    bitBufLen = 0;
659 @@ -450,6 +450,7 @@
660    GBool haveBPC, haveCSMode;
661  
662    csPrec = 0; // make gcc happy
663 +  Guint num_components = 0;
664    haveBPC = haveCSMode = gFalse;
665    str->reset();
666    if (str->lookChar() == 0xff) {
667 @@ -463,7 +464,7 @@
668         cover(1);
669         if (readULong(&dummy) &&
670             readULong(&dummy) &&
671 -           readUWord(&dummy) &&
672 +           readUWord(&num_components) &&
673             readUByte(&bpc1) &&
674             readUByte(&dummy) &&
675             readUByte(&dummy) &&
676 @@ -519,6 +520,9 @@
677        }
678      }
679    }
680 +  if(*csMode == streamCSDeviceRGB && num_components == 4) {
681 +    *csMode = streamCSDeviceRGBX;
682 +  }
683    str->close();
684  }
685  
686 --- xpdf/Lexer.cc.orig  2010-05-18 11:22:18.000000000 -0700
687 +++ xpdf/Lexer.cc       2010-05-18 11:22:18.000000000 -0700
688 @@ -74,6 +74,7 @@
689      curStr.streamReset();
690    }
691  }
692 +static int illegalChars = 0;
693  
694  Lexer::~Lexer() {
695    if (!curStr.isNone()) {
696 @@ -83,6 +84,9 @@
697    if (freeArray) {
698      delete streams;
699    }
700 +  if(illegalChars)
701 +      error(0, "Illegal characters in hex string (%d)", illegalChars);
702 +  illegalChars = 0;
703  }
704  
705  int Lexer::getChar() {
706 @@ -330,7 +334,8 @@
707         } else if (c2 >= 'a' && c2 <= 'f') {
708           c += c2 - 'a' + 10;
709         } else {
710 -         error(getPos(), "Illegal digit in hex char in name");
711 +         illegalChars++;
712 +         //error(getPos(), "Illegal digit in hex char in name");
713         }
714        }
715       notEscChar:
716 @@ -384,8 +389,10 @@
717             c2 += c - 'A' + 10;
718           else if (c >= 'a' && c <= 'f')
719             c2 += c - 'a' + 10;
720 -         else
721 -           error(getPos(), "Illegal character <%02x> in hex string", c);
722 +         else {
723 +           illegalChars++;
724 +           //error(getPos(), "Illegal character <%02x> in hex string", c);
725 +         }
726           if (++m == 2) {
727             if (n == tokBufSize) {
728               if (!s)
729 @@ -421,7 +428,8 @@
730        tokBuf[2] = '\0';
731        obj->initCmd(tokBuf);
732      } else {
733 -      error(getPos(), "Illegal character '>'");
734 +      illegalChars++;
735 +      //error(getPos(), "Illegal character '>'");
736        obj->initError();
737      }
738      break;
739 @@ -430,7 +438,8 @@
740    case ')':
741    case '{':
742    case '}':
743 -    error(getPos(), "Illegal character '%c'", c);
744 +    //error(getPos(), "Illegal character '%c'", c);
745 +    illegalChars++;
746      obj->initError();
747      break;
748  
749 @@ -459,7 +468,6 @@
750      }
751      break;
752    }
753 -
754    return obj;
755  }
756  
757 --- xpdf/Link.cc.orig   2010-05-18 11:22:18.000000000 -0700
758 +++ xpdf/Link.cc        2010-05-18 11:22:18.000000000 -0700
759 @@ -430,10 +430,9 @@
760        delete dest;
761        dest = NULL;
762      }
763 -
764    // error
765    } else {
766 -    error(-1, "Illegal annotation destination");
767 +    error(-1, "Illegal annotation destination %d", destObj->getType());
768    }
769  }
770  
771 @@ -468,10 +467,9 @@
772        delete dest;
773        dest = NULL;
774      }
775 -
776    // error
777    } else {
778 -    error(-1, "Illegal annotation destination");
779 +    error(-1, "Illegal annotation destination %d", destObj->getType());
780    }
781  }
782  
783 --- xpdf/OutputDev.h.orig       2010-05-18 11:22:18.000000000 -0700
784 +++ xpdf/OutputDev.h    2010-05-18 11:22:18.000000000 -0700
785 @@ -17,6 +17,7 @@
786  
787  #include "gtypes.h"
788  #include "CharTypes.h"
789 +#include "Object.h"
790  
791  class GString;
792  class GfxState;
793 --- xpdf/SplashFTFont.cc.orig   2010-05-18 11:22:18.000000000 -0700
794 +++ xpdf/SplashFTFont.cc        2010-05-18 11:22:18.000000000 -0700
795 @@ -46,6 +46,7 @@
796    int x, y;
797  
798    face = fontFileA->face;
799 +  
800    if (FT_New_Size(face, &sizeObj)) {
801      return;
802    }
803 @@ -54,6 +55,10 @@
804    if (FT_Set_Pixel_Sizes(face, 0, (int)size)) {
805      return;
806    }
807
808 +  this->ascender = face->ascender;
809 +  this->descender = face->descender;
810 +
811    // if the textMat values are too small, FreeType's fixed point
812    // arithmetic doesn't work so well
813    textScale = splashSqrt(textMat[2]*textMat[2] + textMat[3]*textMat[3]) / size;
814 @@ -228,6 +233,12 @@
815    GBool needClose;
816  };
817  
818 +int SplashFTFont::getNumChars()
819 +{
820 +  SplashFTFontFile* ff = (SplashFTFontFile *)fontFile;
821 +  return ff->face->num_glyphs;
822 +}
823 +
824  SplashPath *SplashFTFont::getGlyphPath(int c) {
825    static FT_Outline_Funcs outlineFuncs = {
826  #if FREETYPE_MINOR <= 1
827 @@ -249,6 +260,8 @@
828    FT_UInt gid;
829    FT_Glyph glyph;
830  
831 +  this->last_advance = -1;
832 +
833    ff = (SplashFTFontFile *)fontFile;
834    ff->face->size = sizeObj;
835    FT_Set_Transform(ff->face, &textMatrix, NULL);
836 @@ -262,17 +275,24 @@
837      // skip the TrueType notdef glyph
838      return NULL;
839    }
840 -  if (FT_Load_Glyph(ff->face, gid, FT_LOAD_NO_BITMAP)) {
841 +  int error = 0;
842 +  if ((error=FT_Load_Glyph(ff->face, gid, FT_LOAD_NO_BITMAP|FT_LOAD_NO_HINTING))) {
843 +      fprintf(stderr, "Truetype wasn't able to load glyph %d, error %d\n", gid, error);
844      return NULL;
845    }
846    if (FT_Get_Glyph(slot, &glyph)) {
847      return NULL;
848    }
849 +  this->last_advance = glyph->advance.x/65536.0;
850 +
851    path.path = new SplashPath();
852    path.textScale = textScale;
853    path.needClose = gFalse;
854 -  FT_Outline_Decompose(&((FT_OutlineGlyph)glyph)->outline,
855 +  error = FT_Outline_Decompose(&((FT_OutlineGlyph)glyph)->outline,
856                        &outlineFuncs, &path);
857 +  if(error) {
858 +      fprintf(stderr, "Truetype wasn't able to read glyph %d, error %d\n", gid, error);
859 +  }
860    if (path.needClose) {
861      path.path->close();
862    }
863 --- xpdf/SplashFTFont.h.orig    2010-05-18 11:22:18.000000000 -0700
864 +++ xpdf/SplashFTFont.h 2010-05-18 11:22:18.000000000 -0700
865 @@ -42,6 +42,9 @@
866    virtual GBool makeGlyph(int c, int xFrac, int yFrac,
867                           SplashGlyphBitmap *bitmap);
868  
869 +  // return the number of characters in this font
870 +  virtual int getNumChars();
871 +
872    // Return the path for a glyph.
873    virtual SplashPath *getGlyphPath(int c);
874  
875 --- xpdf/SplashFTFontEngine.cc.orig     2010-05-18 11:22:18.000000000 -0700
876 +++ xpdf/SplashFTFontEngine.cc  2010-05-18 11:22:18.000000000 -0700
877 @@ -13,9 +13,7 @@
878  #endif
879  
880  #include <stdio.h>
881 -#ifndef WIN32
882  #  include <unistd.h>
883 -#endif
884  #include "gmem.h"
885  #include "GString.h"
886  #include "gfile.h"
887 --- xpdf/SplashFont.cc.orig     2010-05-18 11:22:18.000000000 -0700
888 +++ xpdf/SplashFont.cc  2010-05-18 11:22:18.000000000 -0700
889 @@ -48,6 +48,10 @@
890    cacheTags = NULL;
891  
892    xMin = yMin = xMax = yMax = 0;
893 +
894 +  last_advance = -1;
895 +  ascender = -1;
896 +  descender = -1;
897  }
898  
899  void SplashFont::initCache() {
900 --- xpdf/SplashFont.h.orig      2010-05-18 11:22:18.000000000 -0700
901 +++ xpdf/SplashFont.h   2010-05-18 11:22:18.000000000 -0700
902 @@ -73,6 +73,9 @@
903    virtual GBool makeGlyph(int c, int xFrac, int yFrac,
904                           SplashGlyphBitmap *bitmap) = 0;
905  
906 +  // return the number of characters in this font
907 +  virtual int getNumChars() = 0;
908 +
909    // Return the path for a glyph.
910    virtual SplashPath *getGlyphPath(int c) = 0;
911  
912 @@ -83,6 +86,9 @@
913    void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA)
914      { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
915  
916 +  double ascender;
917 +  double descender;
918 +  double last_advance; //set after getGlyphPath()
919  protected:
920  
921    SplashFontFile *fontFile;
922 --- xpdf/SplashFontFile.cc.orig 2010-05-18 11:22:18.000000000 -0700
923 +++ xpdf/SplashFontFile.cc      2010-05-18 11:22:18.000000000 -0700
924 @@ -11,9 +11,7 @@
925  #endif
926  
927  #include <stdio.h>
928 -#ifndef WIN32
929 -#  include <unistd.h>
930 -#endif
931 +#include <unistd.h>
932  #include "GString.h"
933  #include "SplashFontFile.h"
934  #include "SplashFontFileID.h"
935 --- xpdf/SplashOutputDev.cc.orig        2010-05-18 11:22:18.000000000 -0700
936 +++ xpdf/SplashOutputDev.cc     2010-05-18 11:22:18.000000000 -0700
937 @@ -13,6 +13,7 @@
938  #endif
939  
940  #include <string.h>
941 +#include <unistd.h>
942  #include <math.h>
943  #include "gfile.h"
944  #include "GlobalParams.h"
945 @@ -2646,9 +2647,9 @@
946  
947    softMask = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
948                               1, splashModeMono8, gFalse);
949 -  memset(softMask->getDataPtr(), 0,
950 -        softMask->getRowSize() * softMask->getHeight());
951 +  memset(softMask->getDataPtr(), 0x00, softMask->getRowSize()*softMask->getHeight());
952    p = softMask->getDataPtr() + ty * softMask->getRowSize() + tx;
953 +  if (tx<softMask->getWidth() && ty<softMask->getHeight())
954    for (y = 0; y < tBitmap->getHeight(); ++y) {
955      for (x = 0; x < tBitmap->getWidth(); ++x) {
956        tBitmap->getPixel(x, y, color);
957 --- xpdf/SplashOutputDev.h.orig 2010-05-18 11:22:18.000000000 -0700
958 +++ xpdf/SplashOutputDev.h      2010-05-18 11:22:18.000000000 -0700
959 @@ -196,6 +196,9 @@
960    virtual void setVectorAntialias(GBool vaa);
961  #endif
962  
963 +  void doUpdateFont(GfxState *state);
964 +  
965 +  SplashPath *convertPath(GfxState *state, GfxPath *path);
966  private:
967  
968    void setupScreenParams(double hDPI, double vDPI);
969 @@ -204,8 +207,6 @@
970  #else
971    SplashPattern *getColor(GfxGray gray, GfxRGB *rgb);
972  #endif
973 -  SplashPath *convertPath(GfxState *state, GfxPath *path);
974 -  void doUpdateFont(GfxState *state);
975    void drawType3Glyph(T3FontCache *t3Font,
976                       T3FontCacheTag *tag, Guchar *data);
977    static GBool imageMaskSrc(void *data, SplashColorPtr line);
978 --- xpdf/SplashScreen.cc.orig   2010-05-18 11:22:18.000000000 -0700
979 +++ xpdf/SplashScreen.cc        2010-05-18 11:22:18.000000000 -0700
980 @@ -363,6 +363,8 @@
981  int SplashScreen::test(int x, int y, Guchar value) {
982    int xx, yy;
983  
984 +  return 1;
985 +
986    if (value < minVal) {
987      return 0;
988    }
989 --- xpdf/SplashXPathScanner.cc.orig     2010-05-18 11:22:18.000000000 -0700
990 +++ xpdf/SplashXPathScanner.cc  2010-05-18 11:22:18.000000000 -0700
991 @@ -394,10 +394,10 @@
992           *p++ &= mask;
993           xx = (xx & ~7) + 8;
994         }
995 -       for (; xx + 7 <= xx0; xx += 8) {
996 +       for (; xx + 7 < xx0; xx += 8) {
997           *p++ = 0x00;
998         }
999 -       if (xx <= xx0) {
1000 +       if (xx < xx0) {
1001           *p &= 0xff >> (xx0 & 7);
1002         }
1003        }
1004 @@ -417,10 +417,10 @@
1005         *p++ &= mask;
1006         xx = (xx & ~7) + 8;
1007        }
1008 -      for (; xx + 7 <= xx0; xx += 8) {
1009 +      for (; xx + 7 < xx0; xx += 8) {
1010         *p++ = 0x00;
1011        }
1012 -      if (xx <= xx0) {
1013 +      if (xx < xx0) {
1014         *p &= 0xff >> (xx0 & 7);
1015        }
1016      }
1017 --- xpdf/Stream.cc.orig 2010-05-18 11:22:18.000000000 -0700
1018 +++ xpdf/Stream.cc      2010-05-18 11:22:18.000000000 -0700
1019 @@ -18,6 +18,8 @@
1020  #include <limits.h>
1021  #ifndef WIN32
1022  #include <unistd.h>
1023 +#else
1024 +extern "C" int unlink(char *filename);
1025  #endif
1026  #include <string.h>
1027  #include <ctype.h>
1028 @@ -2456,6 +2460,9 @@
1029    // check for an EOB run
1030    if (eobRun > 0) {
1031      while (i <= scanInfo.lastCoeff) {
1032 +      if(i>=64) {
1033 +         return gFalse;
1034 +      }
1035        j = dctZigZag[i++];
1036        if (data[j] != 0) {
1037         if ((bit = readBit()) == EOF) {
1038 @@ -2480,6 +2487,9 @@
1039      if (c == 0xf0) {
1040        k = 0;
1041        while (k < 16) {
1042 +        if(i>=64) {
1043 +         return gFalse;
1044 +       }
1045         j = dctZigZag[i++];
1046         if (data[j] == 0) {
1047           ++k;
1048 @@ -2505,6 +2515,9 @@
1049        }
1050        eobRun += 1 << j;
1051        while (i <= scanInfo.lastCoeff) {
1052 +       if(i>=64) {
1053 +         return gFalse;
1054 +       }
1055         j = dctZigZag[i++];
1056         if (data[j] != 0) {
1057           if ((bit = readBit()) == EOF) {
1058 @@ -2527,6 +2540,9 @@
1059        }
1060        k = 0;
1061        do {
1062 +       if(i>=64) {
1063 +         return gFalse;
1064 +       }
1065         j = dctZigZag[i++];
1066         while (data[j] != 0) {
1067           if ((bit = readBit()) == EOF) {
1068 @@ -2535,6 +2551,9 @@
1069           if (bit) {
1070             data[j] += 1 << scanInfo.al;
1071           }
1072 +         if(i>=64) {
1073 +           return gFalse;
1074 +         }
1075           j = dctZigZag[i++];
1076         }
1077         ++k;
1078 --- xpdf/Stream.h.orig  2010-05-18 11:22:18.000000000 -0700
1079 +++ xpdf/Stream.h       2010-05-18 11:22:18.000000000 -0700
1080 @@ -41,7 +41,8 @@
1081    streamCSNone,
1082    streamCSDeviceGray,
1083    streamCSDeviceRGB,
1084 -  streamCSDeviceCMYK
1085 +  streamCSDeviceCMYK,
1086 +  streamCSDeviceRGBX
1087  };
1088  
1089  //------------------------------------------------------------------------
1090 --- xpdf/TextOutputDev.h.orig   2010-05-18 11:22:18.000000000 -0700
1091 +++ xpdf/TextOutputDev.h        2010-05-18 11:22:18.000000000 -0700
1092 @@ -170,6 +170,7 @@
1093    friend class TextFlow;
1094    friend class TextWordList;
1095    friend class TextPage;
1096 +  friend class XMLOutputDev;
1097  };
1098  
1099  //------------------------------------------------------------------------
1100 --- xpdf/gfile.cc.orig  2010-05-18 11:22:18.000000000 -0700
1101 +++ xpdf/gfile.cc       2010-05-18 11:22:18.000000000 -0700
1102 @@ -439,6 +439,52 @@
1103  #endif
1104  }
1105  
1106 +static char* getTempDir()
1107 +{
1108 +#ifdef WIN32
1109 +    char*dir = getenv("TMP");
1110 +    if(!dir) dir = getenv("TEMP");
1111 +    if(!dir) dir = getenv("tmp");
1112 +    if(!dir) dir = getenv("temp");
1113 +    if(!dir) dir = "C:\\";
1114 +#else
1115 +    char* dir = "/tmp/";
1116 +#endif
1117 +    return dir;
1118 +}
1119 +
1120 +char* mktmpname(char*ptr) {
1121 +    static char tmpbuf[128];
1122 +    char*dir = getTempDir();
1123 +    int l = strlen(dir);
1124 +    char*sep = "";
1125 +    if(!ptr)
1126 +       ptr = tmpbuf;
1127 +    if(l && dir[l-1]!='/' && dir[l-1]!='\\') {
1128 +#ifdef WIN32
1129 +       sep = "\\";
1130 +#else
1131 +       sep = "/";
1132 +#endif
1133 +    }
1134 +
1135 + //   used to be mktemp. This does remove the warnings, but
1136 + //   It's not exactly an improvement.
1137 +#ifdef HAVE_LRAND48
1138 +    sprintf(ptr, "%s%s%08x%08x",dir,sep,(unsigned int)lrand48(),(unsigned int)lrand48());
1139 +#else
1140 +#   ifdef HAVE_RAND
1141 +       sprintf(ptr, "%s%s%08x%08x",dir,sep,rand(),rand());
1142 +#   else
1143 +       static int count = 1;
1144 +       sprintf(ptr, "%s%s%08x%04x%04x",dir,sep,time(0),(unsigned int)tmpbuf^((unsigned int)tmpbuf)>>16,count);
1145 +       count ++;
1146 +#   endif
1147 +#endif
1148 +     return ptr;
1149 +}
1150 +
1151 +
1152  GBool openTempFile(GString **name, FILE **f, char *mode, char *ext) {
1153  #if defined(WIN32)
1154    //---------- Win32 ----------
1155 @@ -460,7 +506,7 @@
1156    s->append("x");
1157    t = (int)time(NULL);
1158    for (i = 0; i < 1000; ++i) {
1159 -    sprintf(buf, "%d", t + i);
1160 +    sprintf(buf, "%08x-%08x", t + i, GetCurrentThreadId());
1161      s2 = s->copy()->append(buf);
1162      if (ext) {
1163        s2->append(ext);
1164 @@ -468,8 +514,7 @@
1165      if (!(f2 = fopen(s2->getCString(), "r"))) {
1166        if (!(f2 = fopen(s2->getCString(), mode))) {
1167         delete s2;
1168 -       delete s;
1169 -       return gFalse;
1170 +        continue;
1171        }
1172        *name = s2;
1173        *f = f2;
1174 @@ -479,6 +524,7 @@
1175      fclose(f2);
1176      delete s2;
1177    }
1178 +  fprintf(stderr, "Couldn't create temporary file\n");
1179    delete s;
1180    return gFalse;
1181  #elif defined(VMS) || defined(__EMX__) || defined(ACORN) || defined(MACOS)
1182 @@ -489,7 +535,7 @@
1183    // with this file name after the tmpnam call and before the fopen
1184    // call.  I will happily accept fixes to this function for non-Unix
1185    // OSs.
1186 -  if (!(s = tmpnam(NULL))) {
1187 +  if (!(s = mktmpname(NULL))) {
1188      return gFalse;
1189    }
1190    *name = new GString(s);
1191 @@ -516,7 +562,7 @@
1192      (*name)->append("/XXXXXX")->append(ext);
1193      fd = mkstemps((*name)->getCString(), strlen(ext));
1194  #else
1195 -    if (!(s = tmpnam(NULL))) {
1196 +    if (!(s = mktmpname(NULL))) {
1197        return gFalse;
1198      }
1199      *name = new GString(s);
1200 @@ -533,7 +579,7 @@
1201      (*name)->append("/XXXXXX");
1202      fd = mkstemp((*name)->getCString());
1203  #else // HAVE_MKSTEMP
1204 -    if (!(s = tmpnam(NULL))) {
1205 +    if (!(s = mktmpname(NULL))) {
1206        return gFalse;
1207      }
1208      *name = new GString(s);
1209 --- xpdf/gfile.h.orig   2010-05-18 11:22:18.000000000 -0700
1210 +++ xpdf/gfile.h        2010-05-18 11:22:18.000000000 -0700
1211 @@ -58,6 +58,9 @@
1212  // Get current directory.
1213  extern GString *getCurrentDir();
1214  
1215 +/* create a temporary filename */
1216 +char* mktmpname(char*ptr);
1217 +
1218  // Append a file name to a path string.  <path> may be an empty
1219  // string, denoting the current directory).  Returns <path>.
1220  extern GString *appendToPath(GString *path, char *fileName);
1221 --- xpdf/JBIG2Stream.cc.orig    2010-05-18 11:33:21.000000000 -0700
1222 +++ xpdf/JBIG2Stream.cc 2010-06-03 16:55:03.000000000 -0700
1223 @@ -6,7 +6,24 @@
1224  //
1225  //========================================================================
1226  
1227 -#include <aconf.h>
1228 +//========================================================================
1229 +//
1230 +// Modified under the Poppler project - http://poppler.freedesktop.org
1231 +//
1232 +// All changes made under the Poppler project to this file are licensed
1233 +// under GPL version 2 or later
1234 +//
1235 +// Copyright (C) 2006 Raj Kumar <rkumar@archive.org>
1236 +// Copyright (C) 2006 Paul Walmsley <paul@booyaka.com>
1237 +// Copyright (C) 2006-2009 Albert Astals Cid <aacid@kde.org>
1238 +// Copyright (C) 2009 David Benjamin <davidben@mit.edu>
1239 +//
1240 +// To see a description of the changes please see the Changelog file that
1241 +// came with your tarball or type make ChangeLog if you are building from git
1242 +//
1243 +//========================================================================
1244 +
1245 +#include <config.h>
1246  
1247  #ifdef USE_GCC_PRAGMAS
1248  #pragma implementation
1249 @@ -24,8 +41,8 @@
1250  
1251  //------------------------------------------------------------------------
1252  
1253 -static int contextSize[4] = { 16, 13, 10, 10 };
1254 -static int refContextSize[2] = { 13, 10 };
1255 +static const int contextSize[4] = { 16, 13, 10, 10 };
1256 +static const int refContextSize[2] = { 13, 10 };
1257  
1258  //------------------------------------------------------------------------
1259  // JBIG2HuffmanTable
1260 @@ -42,7 +59,7 @@
1261    Guint prefix;
1262  };
1263  
1264 -JBIG2HuffmanTable huffTableA[] = {
1265 +static JBIG2HuffmanTable huffTableA[] = {
1266    {     0, 1,  4,              0x000 },
1267    {    16, 2,  8,              0x002 },
1268    {   272, 3, 16,              0x006 },
1269 @@ -50,7 +67,7 @@
1270    {     0, 0, jbig2HuffmanEOT, 0     }
1271  };
1272  
1273 -JBIG2HuffmanTable huffTableB[] = {
1274 +static JBIG2HuffmanTable huffTableB[] = {
1275    {     0, 1,  0,              0x000 },
1276    {     1, 2,  0,              0x002 },
1277    {     2, 3,  0,              0x006 },
1278 @@ -61,7 +78,7 @@
1279    {     0, 0, jbig2HuffmanEOT, 0     }
1280  };
1281  
1282 -JBIG2HuffmanTable huffTableC[] = {
1283 +static JBIG2HuffmanTable huffTableC[] = {
1284    {     0, 1,  0,              0x000 },
1285    {     1, 2,  0,              0x002 },
1286    {     2, 3,  0,              0x006 },
1287 @@ -74,7 +91,7 @@
1288    {     0, 0, jbig2HuffmanEOT, 0     }
1289  };
1290  
1291 -JBIG2HuffmanTable huffTableD[] = {
1292 +static JBIG2HuffmanTable huffTableD[] = {
1293    {     1, 1,  0,              0x000 },
1294    {     2, 2,  0,              0x002 },
1295    {     3, 3,  0,              0x006 },
1296 @@ -84,7 +101,7 @@
1297    {     0, 0, jbig2HuffmanEOT, 0     }
1298  };
1299  
1300 -JBIG2HuffmanTable huffTableE[] = {
1301 +static JBIG2HuffmanTable huffTableE[] = {
1302    {     1, 1,  0,              0x000 },
1303    {     2, 2,  0,              0x002 },
1304    {     3, 3,  0,              0x006 },
1305 @@ -96,7 +113,7 @@
1306    {     0, 0, jbig2HuffmanEOT, 0     }
1307  };
1308  
1309 -JBIG2HuffmanTable huffTableF[] = {
1310 +static JBIG2HuffmanTable huffTableF[] = {
1311    {     0, 2,  7,              0x000 },
1312    {   128, 3,  7,              0x002 },
1313    {   256, 3,  8,              0x003 },
1314 @@ -114,7 +131,7 @@
1315    {     0, 0, jbig2HuffmanEOT, 0     }
1316  };
1317  
1318 -JBIG2HuffmanTable huffTableG[] = {
1319 +static JBIG2HuffmanTable huffTableG[] = {
1320    {  -512, 3,  8,              0x000 },
1321    {   256, 3,  8,              0x001 },
1322    {   512, 3,  9,              0x002 },
1323 @@ -133,7 +150,7 @@
1324    {     0, 0, jbig2HuffmanEOT, 0     }
1325  };
1326  
1327 -JBIG2HuffmanTable huffTableH[] = {
1328 +static JBIG2HuffmanTable huffTableH[] = {
1329    {     0, 2,  1,              0x000 },
1330    {     0, 2, jbig2HuffmanOOB, 0x001 },
1331    {     4, 3,  4,              0x004 },
1332 @@ -158,7 +175,7 @@
1333    {     0, 0, jbig2HuffmanEOT, 0     }
1334  };
1335  
1336 -JBIG2HuffmanTable huffTableI[] = {
1337 +static JBIG2HuffmanTable huffTableI[] = {
1338    {     0, 2, jbig2HuffmanOOB, 0x000 },
1339    {    -1, 3,  1,              0x002 },
1340    {     1, 3,  1,              0x003 },
1341 @@ -184,7 +201,7 @@
1342    {     0, 0, jbig2HuffmanEOT, 0     }
1343  };
1344  
1345 -JBIG2HuffmanTable huffTableJ[] = {
1346 +static JBIG2HuffmanTable huffTableJ[] = {
1347    {    -2, 2,  2,              0x000 },
1348    {     6, 2,  6,              0x001 },
1349    {     0, 2, jbig2HuffmanOOB, 0x002 },
1350 @@ -209,7 +226,7 @@
1351    {     0, 0, jbig2HuffmanEOT, 0     }
1352  };
1353  
1354 -JBIG2HuffmanTable huffTableK[] = {
1355 +static JBIG2HuffmanTable huffTableK[] = {
1356    {     1, 1,  0,              0x000 },
1357    {     2, 2,  1,              0x002 },
1358    {     4, 4,  0,              0x00c },
1359 @@ -226,7 +243,7 @@
1360    {     0, 0, jbig2HuffmanEOT, 0     }
1361  };
1362  
1363 -JBIG2HuffmanTable huffTableL[] = {
1364 +static JBIG2HuffmanTable huffTableL[] = {
1365    {     1, 1,  0,              0x000 },
1366    {     2, 2,  0,              0x002 },
1367    {     3, 3,  1,              0x006 },
1368 @@ -243,7 +260,7 @@
1369    {     0, 0, jbig2HuffmanEOT, 0     }
1370  };
1371  
1372 -JBIG2HuffmanTable huffTableM[] = {
1373 +static JBIG2HuffmanTable huffTableM[] = {
1374    {     1, 1,  0,              0x000 },
1375    {     2, 3,  0,              0x004 },
1376    {     7, 3,  3,              0x005 },
1377 @@ -260,7 +277,7 @@
1378    {     0, 0, jbig2HuffmanEOT, 0     }
1379  };
1380  
1381 -JBIG2HuffmanTable huffTableN[] = {
1382 +static JBIG2HuffmanTable huffTableN[] = {
1383    {     0, 1,  0,              0x000 },
1384    {    -2, 3,  0,              0x004 },
1385    {    -1, 3,  0,              0x005 },
1386 @@ -269,7 +286,7 @@
1387    {     0, 0, jbig2HuffmanEOT, 0     }
1388  };
1389  
1390 -JBIG2HuffmanTable huffTableO[] = {
1391 +static JBIG2HuffmanTable huffTableO[] = {
1392    {     0, 1,  0,              0x000 },
1393    {    -1, 3,  0,              0x004 },
1394    {     1, 3,  0,              0x005 },
1395 @@ -473,7 +490,7 @@
1396  }
1397  
1398  int JBIG2MMRDecoder::get2DCode() {
1399 -  CCITTCode *p;
1400 +  const CCITTCode *p;
1401  
1402    if (bufLen == 0) {
1403      buf = str->getChar() & 0xff;
1404 @@ -500,7 +517,7 @@
1405  }
1406  
1407  int JBIG2MMRDecoder::getWhiteCode() {
1408 -  CCITTCode *p;
1409 +  const CCITTCode *p;
1410    Guint code;
1411  
1412    if (bufLen == 0) {
1413 @@ -543,7 +560,7 @@
1414  }
1415  
1416  int JBIG2MMRDecoder::getBlackCode() {
1417 -  CCITTCode *p;
1418 +  const CCITTCode *p;
1419    Guint code;
1420  
1421    if (bufLen == 0) {
1422 @@ -670,6 +687,7 @@
1423    void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
1424    Guchar *getDataPtr() { return data; }
1425    int getDataSize() { return h * line; }
1426 +  GBool isOk() { return data != NULL; }
1427  
1428  private:
1429  
1430 @@ -685,10 +703,11 @@
1431    w = wA;
1432    h = hA;
1433    line = (wA + 7) >> 3;
1434 +
1435    if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
1436 -    // force a call to gmalloc(-1), which will throw an exception
1437 -    h = -1;
1438 -    line = 2;
1439 +    error(-1, "invalid width/height");
1440 +    data = NULL;
1441 +    return;
1442    }
1443    // need to allocate one extra guard byte for use in combine()
1444    data = (Guchar *)gmalloc(h * line + 1);
1445 @@ -701,10 +720,11 @@
1446    w = bitmap->w;
1447    h = bitmap->h;
1448    line = bitmap->line;
1449 +
1450    if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
1451 -    // force a call to gmalloc(-1), which will throw an exception
1452 -    h = -1;
1453 -    line = 2;
1454 +    error(-1, "invalid width/height");
1455 +    data = NULL;
1456 +    return;
1457    }
1458    // need to allocate one extra guard byte for use in combine()
1459    data = (Guchar *)gmalloc(h * line + 1);
1460 @@ -735,6 +755,9 @@
1461  
1462  void JBIG2Bitmap::expand(int newH, Guint pixel) {
1463    if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
1464 +    error(-1, "invalid width/height");
1465 +    gfree(data);
1466 +    data = NULL;
1467      return;
1468    }
1469    // need to allocate one extra guard byte for use in combine()
1470 @@ -1002,6 +1025,7 @@
1471    Guint getSize() { return size; }
1472    void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1473    JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1474 +  GBool isOk() { return bitmaps != NULL; }
1475    void setGenericRegionStats(JArithmeticDecoderStats *stats)
1476      { genericRegionStats = stats; }
1477    void setRefinementRegionStats(JArithmeticDecoderStats *stats)
1478 @@ -1022,13 +1046,9 @@
1479  JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
1480    JBIG2Segment(segNumA)
1481  {
1482 -  Guint i;
1483 -
1484    size = sizeA;
1485    bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
1486 -  for (i = 0; i < size; ++i) {
1487 -    bitmaps[i] = NULL;
1488 -  }
1489 +  if (!bitmaps) size = 0;
1490    genericRegionStats = NULL;
1491    refinementRegionStats = NULL;
1492  }
1493 @@ -1037,9 +1057,7 @@
1494    Guint i;
1495  
1496    for (i = 0; i < size; ++i) {
1497 -    if (bitmaps[i]) {
1498 -      delete bitmaps[i];
1499 -    }
1500 +    delete bitmaps[i];
1501    }
1502    gfree(bitmaps);
1503    if (genericRegionStats) {
1504 @@ -1247,6 +1265,7 @@
1505    Guint segNum, segFlags, segType, page, segLength;
1506    Guint refFlags, nRefSegs;
1507    Guint *refSegs;
1508 +  int segDataPos;
1509    int c1, c2, c3;
1510    Guint i;
1511  
1512 @@ -1314,6 +1333,9 @@
1513        goto eofError2;
1514      }
1515  
1516 +    // keep track of the start of the segment data 
1517 +    segDataPos = getPos();
1518 +
1519      // check for missing page information segment
1520      if (!pageBitmap && ((segType >= 4 && segType <= 7) ||
1521                         (segType >= 20 && segType <= 43))) {
1522 @@ -1398,6 +1420,45 @@
1523        break;
1524      }
1525  
1526 +    // Make sure the segment handler read all of the bytes in the 
1527 +    // segment data, unless this segment is marked as having an
1528 +    // unknown length (section 7.2.7 of the JBIG2 Final Committee Draft)
1529 +
1530 +    if (segLength != 0xffffffff) {
1531 +
1532 +      int segExtraBytes = segDataPos + segLength - getPos();
1533 +      if (segExtraBytes > 0) {
1534 +
1535 +       // If we didn't read all of the bytes in the segment data,
1536 +       // indicate an error, and throw away the rest of the data.
1537 +       
1538 +       // v.3.1.01.13 of the LuraTech PDF Compressor Server will
1539 +       // sometimes generate an extraneous NULL byte at the end of
1540 +       // arithmetic-coded symbol dictionary segments when numNewSyms
1541 +       // == 0.  Segments like this often occur for blank pages.
1542 +       
1543 +       error(getPos(), "%d extraneous byte%s after segment",
1544 +             segExtraBytes, (segExtraBytes > 1) ? "s" : "");
1545 +       
1546 +       // Burn through the remaining bytes -- inefficient, but
1547 +       // hopefully we're not doing this much
1548 +       
1549 +       int trash;
1550 +       for (int i = segExtraBytes; i > 0; i--) {
1551 +         readByte(&trash);
1552 +       }
1553 +       
1554 +      } else if (segExtraBytes < 0) {
1555 +       
1556 +       // If we read more bytes than we should have, according to the 
1557 +       // segment length field, note an error.
1558 +       
1559 +       error(getPos(), "Previous segment handler read too many bytes");
1560 +       
1561 +      }
1562 +
1563 +    }
1564 +    
1565      gfree(refSegs);
1566    }
1567  
1568 @@ -1493,6 +1554,9 @@
1569    codeTables = new GList();
1570    numInputSyms = 0;
1571    for (i = 0; i < nRefSegs; ++i) {
1572 +    // This is need by bug 12014, returning gFalse makes it not crash
1573 +    // but we end up with a empty page while acroread is able to render
1574 +    // part of it
1575      if ((seg = findSegment(refSegs[i]))) {
1576        if (seg->getType() == jbig2SegSymbolDict) {
1577         j = ((JBIG2SymbolDict *)seg)->getSize();
1578 @@ -1503,8 +1567,11 @@
1579         }
1580         numInputSyms += j;
1581        } else if (seg->getType() == jbig2SegCodeTable) {
1582 -       codeTables->append(seg);
1583 +        codeTables->append(seg);
1584        }
1585 +    } else {
1586 +      delete codeTables;
1587 +      return gFalse;
1588      }
1589    }
1590    if (numInputSyms > UINT_MAX - numNewSyms) {
1591 @@ -1530,12 +1600,11 @@
1592    k = 0;
1593    inputSymbolDict = NULL;
1594    for (i = 0; i < nRefSegs; ++i) {
1595 -    if ((seg = findSegment(refSegs[i]))) {
1596 -      if (seg->getType() == jbig2SegSymbolDict) {
1597 -       inputSymbolDict = (JBIG2SymbolDict *)seg;
1598 -       for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1599 -         bitmaps[k++] = inputSymbolDict->getBitmap(j);
1600 -       }
1601 +    seg = findSegment(refSegs[i]);
1602 +    if (seg != NULL && seg->getType() == jbig2SegSymbolDict) {
1603 +      inputSymbolDict = (JBIG2SymbolDict *)seg;
1604 +      for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1605 +       bitmaps[k++] = inputSymbolDict->getBitmap(j);
1606        }
1607      }
1608    }
1609 @@ -1753,6 +1822,10 @@
1610  
1611    // create the symbol dict object
1612    symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1613 +  if (!symbolDict->isOk()) {
1614 +    delete symbolDict;
1615 +    goto syntaxError;
1616 +  }
1617  
1618    // exported symbol list
1619    i = j = 0;
1620 @@ -1766,6 +1839,7 @@
1621      if (i + run > numInputSyms + numNewSyms ||
1622         (ex && j + run > numExSyms)) {
1623        error(getPos(), "Too many exported symbols in JBIG2 symbol dictionary");
1624 +      for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
1625        delete symbolDict;
1626        goto syntaxError;
1627      }
1628 @@ -1780,6 +1854,7 @@
1629    }
1630    if (j != numExSyms) {
1631      error(getPos(), "Too few symbols in JBIG2 symbol dictionary");
1632 +    for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
1633      delete symbolDict;
1634      goto syntaxError;
1635    }
1636 @@ -2095,18 +2170,20 @@
1637  
1638    gfree(syms);
1639  
1640 -  // combine the region bitmap into the page bitmap
1641 -  if (imm) {
1642 -    if (pageH == 0xffffffff && y + h > curPageH) {
1643 -      pageBitmap->expand(y + h, pageDefPixel);
1644 -    }
1645 -    pageBitmap->combine(bitmap, x, y, extCombOp);
1646 -    delete bitmap;
1647 +  if (bitmap) {
1648 +    // combine the region bitmap into the page bitmap
1649 +    if (imm) {
1650 +      if (pageH == 0xffffffff && y + h > curPageH) {
1651 +        pageBitmap->expand(y + h, pageDefPixel);
1652 +      }
1653 +      pageBitmap->combine(bitmap, x, y, extCombOp);
1654 +      delete bitmap;
1655  
1656 -  // store the region bitmap
1657 -  } else {
1658 -    bitmap->setSegNum(segNum);
1659 -    segments->append(bitmap);
1660 +    // store the region bitmap
1661 +    } else {
1662 +      bitmap->setSegNum(segNum);
1663 +      segments->append(bitmap);
1664 +    }
1665    }
1666  
1667    // clean up the Huffman decoder
1668 @@ -2159,6 +2236,10 @@
1669  
1670    // allocate the bitmap
1671    bitmap = new JBIG2Bitmap(0, w, h);
1672 +  if (!bitmap->isOk()) {
1673 +    delete bitmap;
1674 +    return NULL;
1675 +  }
1676    if (defPixel) {
1677      bitmap->clearToOne();
1678    } else {
1679 @@ -2235,73 +2316,84 @@
1680           ri = 0;
1681         }
1682         if (ri) {
1683 +         GBool decodeSuccess;
1684           if (huff) {
1685 -           huffDecoder->decodeInt(&rdw, huffRDWTable);
1686 -           huffDecoder->decodeInt(&rdh, huffRDHTable);
1687 -           huffDecoder->decodeInt(&rdx, huffRDXTable);
1688 -           huffDecoder->decodeInt(&rdy, huffRDYTable);
1689 -           huffDecoder->decodeInt(&bmSize, huffRSizeTable);
1690 +           decodeSuccess = huffDecoder->decodeInt(&rdw, huffRDWTable);
1691 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdh, huffRDHTable);
1692 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdx, huffRDXTable);
1693 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdy, huffRDYTable);
1694 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&bmSize, huffRSizeTable);
1695             huffDecoder->reset();
1696             arithDecoder->start();
1697           } else {
1698 -           arithDecoder->decodeInt(&rdw, iardwStats);
1699 -           arithDecoder->decodeInt(&rdh, iardhStats);
1700 -           arithDecoder->decodeInt(&rdx, iardxStats);
1701 -           arithDecoder->decodeInt(&rdy, iardyStats);
1702 +           decodeSuccess = arithDecoder->decodeInt(&rdw, iardwStats);
1703 +           decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdh, iardhStats);
1704 +           decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdx, iardxStats);
1705 +           decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdy, iardyStats);
1706 +         }
1707 +         
1708 +         if (decodeSuccess && syms[symID])
1709 +         {
1710 +           refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
1711 +           refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
1712 +
1713 +           symbolBitmap =
1714 +             readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
1715 +                                         rdh + syms[symID]->getHeight(),
1716 +                                         templ, gFalse, syms[symID],
1717 +                                         refDX, refDY, atx, aty);
1718           }
1719 -         refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
1720 -         refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
1721 -
1722 -         symbolBitmap =
1723 -           readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
1724 -                                       rdh + syms[symID]->getHeight(),
1725 -                                       templ, gFalse, syms[symID],
1726 -                                       refDX, refDY, atx, aty);
1727           //~ do we need to use the bmSize value here (in Huffman mode)?
1728         } else {
1729           symbolBitmap = syms[symID];
1730         }
1731  
1732 -       // combine the symbol bitmap into the region bitmap
1733 -       //~ something is wrong here - refCorner shouldn't degenerate into
1734 -       //~   two cases
1735 -       bw = symbolBitmap->getWidth() - 1;
1736 -       bh = symbolBitmap->getHeight() - 1;
1737 -       if (transposed) {
1738 -         switch (refCorner) {
1739 -         case 0: // bottom left
1740 -           bitmap->combine(symbolBitmap, tt, s, combOp);
1741 -           break;
1742 -         case 1: // top left
1743 -           bitmap->combine(symbolBitmap, tt, s, combOp);
1744 -           break;
1745 -         case 2: // bottom right
1746 -           bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1747 -           break;
1748 -         case 3: // top right
1749 -           bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1750 -           break;
1751 +       if (symbolBitmap) {
1752 +         // combine the symbol bitmap into the region bitmap
1753 +         //~ something is wrong here - refCorner shouldn't degenerate into
1754 +         //~   two cases
1755 +         bw = symbolBitmap->getWidth() - 1;
1756 +         bh = symbolBitmap->getHeight() - 1;
1757 +         if (transposed) {
1758 +           switch (refCorner) {
1759 +           case 0: // bottom left
1760 +             bitmap->combine(symbolBitmap, tt, s, combOp);
1761 +             break;
1762 +           case 1: // top left
1763 +             bitmap->combine(symbolBitmap, tt, s, combOp);
1764 +             break;
1765 +           case 2: // bottom right
1766 +             bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1767 +             break;
1768 +           case 3: // top right
1769 +             bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1770 +             break;
1771 +           }
1772 +           s += bh;
1773 +         } else {
1774 +           switch (refCorner) {
1775 +           case 0: // bottom left
1776 +             bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1777 +             break;
1778 +           case 1: // top left
1779 +             bitmap->combine(symbolBitmap, s, tt, combOp);
1780 +             break;
1781 +           case 2: // bottom right
1782 +             bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1783 +             break;
1784 +           case 3: // top right
1785 +             bitmap->combine(symbolBitmap, s, tt, combOp);
1786 +             break;
1787 +           }
1788 +           s += bw;
1789           }
1790 -         s += bh;
1791 -       } else {
1792 -         switch (refCorner) {
1793 -         case 0: // bottom left
1794 -           bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1795 -           break;
1796 -         case 1: // top left
1797 -           bitmap->combine(symbolBitmap, s, tt, combOp);
1798 -           break;
1799 -         case 2: // bottom right
1800 -           bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1801 -           break;
1802 -         case 3: // top right
1803 -           bitmap->combine(symbolBitmap, s, tt, combOp);
1804 -           break;
1805 +         if (ri) {
1806 +           delete symbolBitmap;
1807           }
1808 -         s += bw;
1809 -       }
1810 -       if (ri) {
1811 -         delete symbolBitmap;
1812 +       } else {
1813 +         // NULL symbolBitmap only happens on error
1814 +         delete bitmap;
1815 +         return NULL;
1816         }
1817        }
1818  
1819 @@ -2431,11 +2523,12 @@
1820      error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
1821      return;
1822    }
1823 -  if (!(seg = findSegment(refSegs[0])) ||
1824 -      seg->getType() != jbig2SegPatternDict) {
1825 +  seg = findSegment(refSegs[0]);
1826 +  if (seg == NULL || seg->getType() != jbig2SegPatternDict) {
1827      error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
1828      return;
1829    }
1830 +
1831    patternDict = (JBIG2PatternDict *)seg;
1832    bpp = 0;
1833    i = 1;
1834 @@ -2591,6 +2684,8 @@
1835    // read the bitmap
1836    bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
1837                              NULL, atx, aty, mmr ? length - 18 : 0);
1838 +  if (!bitmap)
1839 +    return;
1840  
1841    // combine the region bitmap into the page bitmap
1842    if (imm) {
1843 @@ -2616,7 +2711,7 @@
1844                                       int *codingLine, int *a0i, int w) {
1845    if (a1 > codingLine[*a0i]) {
1846      if (a1 > w) {
1847 -      error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
1848 +      error(getPos(), "JBIG2 MMR row is wrong length (%d)", a1);
1849        a1 = w;
1850      }
1851      if ((*a0i & 1) ^ blackPixels) {
1852 @@ -2630,7 +2725,7 @@
1853                                          int *codingLine, int *a0i, int w) {
1854    if (a1 > codingLine[*a0i]) {
1855      if (a1 > w) {
1856 -      error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
1857 +      error(getPos(), "JBIG2 MMR row is wrong length (%d)", a1);
1858        a1 = w;
1859      }
1860      if ((*a0i & 1) ^ blackPixels) {
1861 @@ -2657,13 +2752,17 @@
1862    JBIG2Bitmap *bitmap;
1863    GBool ltp;
1864    Guint ltpCX, cx, cx0, cx1, cx2;
1865 -  JBIG2BitmapPtr cxPtr0, cxPtr1;
1866 -  JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3;
1867 +  JBIG2BitmapPtr cxPtr0 = {0}, cxPtr1 = {0};
1868 +  JBIG2BitmapPtr atPtr0 = {0}, atPtr1 = {0}, atPtr2 = {0}, atPtr3 = {0};
1869    int *refLine, *codingLine;
1870    int code1, code2, code3;
1871    int x, y, a0i, b1i, blackPixels, pix, i;
1872  
1873    bitmap = new JBIG2Bitmap(0, w, h);
1874 +  if (!bitmap->isOk()) {
1875 +    delete bitmap;
1876 +    return NULL;
1877 +  }
1878    bitmap->clearToZero();
1879  
1880    //----- MMR decode
1881 @@ -2682,7 +2781,7 @@
1882      // ---> max refLine size = w + 2
1883      codingLine = (int *)gmallocn(w + 1, sizeof(int));
1884      refLine = (int *)gmallocn(w + 2, sizeof(int));
1885 -    codingLine[0] = w;
1886 +    for (i = 0; i < w + 1; ++i) codingLine[i] = w;
1887  
1888      for (y = 0; y < h; ++y) {
1889  
1890 @@ -3093,8 +3192,8 @@
1891      return;
1892    }
1893    if (nRefSegs == 1) {
1894 -    if (!(seg = findSegment(refSegs[0])) ||
1895 -       seg->getType() != jbig2SegBitmap) {
1896 +    seg = findSegment(refSegs[0]);
1897 +    if (seg == NULL || seg->getType() != jbig2SegBitmap) {
1898        error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
1899        return;
1900      }
1901 @@ -3143,11 +3242,24 @@
1902    JBIG2Bitmap *bitmap;
1903    GBool ltp;
1904    Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
1905 -  JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
1906 -  JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
1907 +  JBIG2BitmapPtr cxPtr0 = {0};
1908 +  JBIG2BitmapPtr cxPtr1 = {0};
1909 +  JBIG2BitmapPtr cxPtr2 = {0};
1910 +  JBIG2BitmapPtr cxPtr3 = {0};
1911 +  JBIG2BitmapPtr cxPtr4 = {0};
1912 +  JBIG2BitmapPtr cxPtr5 = {0};
1913 +  JBIG2BitmapPtr cxPtr6 = {0};
1914 +  JBIG2BitmapPtr tpgrCXPtr0 = {0};
1915 +  JBIG2BitmapPtr tpgrCXPtr1 = {0};
1916 +  JBIG2BitmapPtr tpgrCXPtr2 = {0};
1917    int x, y, pix;
1918  
1919    bitmap = new JBIG2Bitmap(0, w, h);
1920 +  if (!bitmap->isOk())
1921 +  {
1922 +    delete bitmap;
1923 +    return NULL;
1924 +  }
1925    bitmap->clearToZero();
1926  
1927    // set up the typical row context
1928 @@ -3332,6 +3444,12 @@
1929    }
1930    pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
1931  
1932 +  if (!pageBitmap->isOk()) {
1933 +    delete pageBitmap;
1934 +    pageBitmap = NULL;
1935 +    return;
1936 +  }
1937 +  
1938    // default pixel value
1939    if (pageDefPixel) {
1940      pageBitmap->clearToOne();