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