19b7bc1ebabf2c0729b11e18c9dccf42451f0fa6
[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 @@ -241,6 +242,12 @@
660    haveCompMap = gFalse;
661    haveChannelDefn = gFalse;
662  
663 +  img.xSize = 0;
664 +  img.ySize = 0;
665 +  img.xOffset = 0;
666 +  img.yOffset = 0;
667 +  curX = 0;
668 +  curY = 0;
669    img.tiles = NULL;
670    bitBuf = 0;
671    bitBufLen = 0;
672 @@ -450,6 +450,7 @@
673    GBool haveBPC, haveCSMode;
674  
675    csPrec = 0; // make gcc happy
676 +  Guint num_components = 0;
677    haveBPC = haveCSMode = gFalse;
678    str->reset();
679    if (str->lookChar() == 0xff) {
680 @@ -463,7 +464,7 @@
681         cover(1);
682         if (readULong(&dummy) &&
683             readULong(&dummy) &&
684 -           readUWord(&dummy) &&
685 +           readUWord(&num_components) &&
686             readUByte(&bpc1) &&
687             readUByte(&dummy) &&
688             readUByte(&dummy) &&
689 @@ -519,6 +520,9 @@
690        }
691      }
692    }
693 +  if(*csMode == streamCSDeviceRGB && num_components == 4) {
694 +    *csMode = streamCSDeviceRGBX;
695 +  }
696    str->close();
697  }
698  
699 --- xpdf/Lexer.cc.orig  2010-05-18 11:22:18.000000000 -0700
700 +++ xpdf/Lexer.cc       2010-05-18 11:22:18.000000000 -0700
701 @@ -74,6 +74,7 @@
702      curStr.streamReset();
703    }
704  }
705 +static int illegalChars = 0;
706  
707  Lexer::~Lexer() {
708    if (!curStr.isNone()) {
709 @@ -83,6 +84,9 @@
710    if (freeArray) {
711      delete streams;
712    }
713 +  if(illegalChars)
714 +      error(0, "Illegal characters in hex string (%d)", illegalChars);
715 +  illegalChars = 0;
716  }
717  
718  int Lexer::getChar() {
719 @@ -330,7 +334,8 @@
720         } else if (c2 >= 'a' && c2 <= 'f') {
721           c += c2 - 'a' + 10;
722         } else {
723 -         error(getPos(), "Illegal digit in hex char in name");
724 +         illegalChars++;
725 +         //error(getPos(), "Illegal digit in hex char in name");
726         }
727        }
728       notEscChar:
729 @@ -384,8 +389,10 @@
730             c2 += c - 'A' + 10;
731           else if (c >= 'a' && c <= 'f')
732             c2 += c - 'a' + 10;
733 -         else
734 -           error(getPos(), "Illegal character <%02x> in hex string", c);
735 +         else {
736 +           illegalChars++;
737 +           //error(getPos(), "Illegal character <%02x> in hex string", c);
738 +         }
739           if (++m == 2) {
740             if (n == tokBufSize) {
741               if (!s)
742 @@ -421,7 +428,8 @@
743        tokBuf[2] = '\0';
744        obj->initCmd(tokBuf);
745      } else {
746 -      error(getPos(), "Illegal character '>'");
747 +      illegalChars++;
748 +      //error(getPos(), "Illegal character '>'");
749        obj->initError();
750      }
751      break;
752 @@ -430,7 +438,8 @@
753    case ')':
754    case '{':
755    case '}':
756 -    error(getPos(), "Illegal character '%c'", c);
757 +    //error(getPos(), "Illegal character '%c'", c);
758 +    illegalChars++;
759      obj->initError();
760      break;
761  
762 @@ -459,7 +468,6 @@
763      }
764      break;
765    }
766 -
767    return obj;
768  }
769  
770 --- xpdf/Link.cc.orig   2010-05-18 11:22:18.000000000 -0700
771 +++ xpdf/Link.cc        2010-05-18 11:22:18.000000000 -0700
772 @@ -430,10 +430,9 @@
773        delete dest;
774        dest = NULL;
775      }
776 -
777    // error
778    } else {
779 -    error(-1, "Illegal annotation destination");
780 +    error(-1, "Illegal annotation destination %d", destObj->getType());
781    }
782  }
783  
784 @@ -468,10 +467,9 @@
785        delete dest;
786        dest = NULL;
787      }
788 -
789    // error
790    } else {
791 -    error(-1, "Illegal annotation destination");
792 +    error(-1, "Illegal annotation destination %d", destObj->getType());
793    }
794  }
795  
796 --- xpdf/OutputDev.h.orig       2010-05-18 11:22:18.000000000 -0700
797 +++ xpdf/OutputDev.h    2010-05-18 11:22:18.000000000 -0700
798 @@ -17,6 +17,7 @@
799  
800  #include "gtypes.h"
801  #include "CharTypes.h"
802 +#include "Object.h"
803  
804  class GString;
805  class GfxState;
806 @@ -94,7 +95,7 @@
807      { return gTrue; }
808  
809    // Start a page.
810 -  virtual void startPage(int pageNum, GfxState *state) {}
811 +  virtual void startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2) {}
812  
813    // End a page.
814    virtual void endPage() {}
815 --- xpdf/SplashFTFont.cc.orig   2010-05-18 11:22:18.000000000 -0700
816 +++ xpdf/SplashFTFont.cc        2010-05-18 11:22:18.000000000 -0700
817 @@ -46,6 +46,7 @@
818    int x, y;
819  
820    face = fontFileA->face;
821 +  
822    if (FT_New_Size(face, &sizeObj)) {
823      return;
824    }
825 @@ -54,6 +55,10 @@
826    if (FT_Set_Pixel_Sizes(face, 0, (int)size)) {
827      return;
828    }
829
830 +  this->ascender = face->ascender;
831 +  this->descender = face->descender;
832 +
833    // if the textMat values are too small, FreeType's fixed point
834    // arithmetic doesn't work so well
835    textScale = splashSqrt(textMat[2]*textMat[2] + textMat[3]*textMat[3]) / size;
836 @@ -228,6 +233,12 @@
837    GBool needClose;
838  };
839  
840 +int SplashFTFont::getNumChars()
841 +{
842 +  SplashFTFontFile* ff = (SplashFTFontFile *)fontFile;
843 +  return ff->face->num_glyphs;
844 +}
845 +
846  SplashPath *SplashFTFont::getGlyphPath(int c) {
847    static FT_Outline_Funcs outlineFuncs = {
848  #if FREETYPE_MINOR <= 1
849 @@ -249,6 +260,8 @@
850    FT_UInt gid;
851    FT_Glyph glyph;
852  
853 +  this->last_advance = -1;
854 +
855    ff = (SplashFTFontFile *)fontFile;
856    ff->face->size = sizeObj;
857    FT_Set_Transform(ff->face, &textMatrix, NULL);
858 @@ -262,17 +275,24 @@
859      // skip the TrueType notdef glyph
860      return NULL;
861    }
862 -  if (FT_Load_Glyph(ff->face, gid, FT_LOAD_NO_BITMAP)) {
863 +  int error = 0;
864 +  if ((error=FT_Load_Glyph(ff->face, gid, FT_LOAD_NO_BITMAP|FT_LOAD_NO_HINTING))) {
865 +      fprintf(stderr, "Truetype wasn't able to load glyph %d, error %d\n", gid, error);
866      return NULL;
867    }
868    if (FT_Get_Glyph(slot, &glyph)) {
869      return NULL;
870    }
871 +  this->last_advance = glyph->advance.x/65536.0;
872 +
873    path.path = new SplashPath();
874    path.textScale = textScale;
875    path.needClose = gFalse;
876 -  FT_Outline_Decompose(&((FT_OutlineGlyph)glyph)->outline,
877 +  error = FT_Outline_Decompose(&((FT_OutlineGlyph)glyph)->outline,
878                        &outlineFuncs, &path);
879 +  if(error) {
880 +      fprintf(stderr, "Truetype wasn't able to read glyph %d, error %d\n", gid, error);
881 +  }
882    if (path.needClose) {
883      path.path->close();
884    }
885 --- xpdf/SplashFTFont.h.orig    2010-05-18 11:22:18.000000000 -0700
886 +++ xpdf/SplashFTFont.h 2010-05-18 11:22:18.000000000 -0700
887 @@ -42,6 +42,9 @@
888    virtual GBool makeGlyph(int c, int xFrac, int yFrac,
889                           SplashGlyphBitmap *bitmap);
890  
891 +  // return the number of characters in this font
892 +  virtual int getNumChars();
893 +
894    // Return the path for a glyph.
895    virtual SplashPath *getGlyphPath(int c);
896  
897 --- xpdf/SplashFTFontEngine.cc.orig     2010-05-18 11:22:18.000000000 -0700
898 +++ xpdf/SplashFTFontEngine.cc  2010-05-18 11:22:18.000000000 -0700
899 @@ -13,9 +13,7 @@
900  #endif
901  
902  #include <stdio.h>
903 -#ifndef WIN32
904  #  include <unistd.h>
905 -#endif
906  #include "gmem.h"
907  #include "GString.h"
908  #include "gfile.h"
909 --- xpdf/SplashFont.cc.orig     2010-05-18 11:22:18.000000000 -0700
910 +++ xpdf/SplashFont.cc  2010-05-18 11:22:18.000000000 -0700
911 @@ -48,6 +48,10 @@
912    cacheTags = NULL;
913  
914    xMin = yMin = xMax = yMax = 0;
915 +
916 +  last_advance = -1;
917 +  ascender = -1;
918 +  descender = -1;
919  }
920  
921  void SplashFont::initCache() {
922 --- xpdf/SplashFont.h.orig      2010-05-18 11:22:18.000000000 -0700
923 +++ xpdf/SplashFont.h   2010-05-18 11:22:18.000000000 -0700
924 @@ -73,6 +73,9 @@
925    virtual GBool makeGlyph(int c, int xFrac, int yFrac,
926                           SplashGlyphBitmap *bitmap) = 0;
927  
928 +  // return the number of characters in this font
929 +  virtual int getNumChars() = 0;
930 +
931    // Return the path for a glyph.
932    virtual SplashPath *getGlyphPath(int c) = 0;
933  
934 @@ -83,6 +86,9 @@
935    void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA)
936      { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
937  
938 +  double ascender;
939 +  double descender;
940 +  double last_advance; //set after getGlyphPath()
941  protected:
942  
943    SplashFontFile *fontFile;
944 --- xpdf/SplashFontFile.cc.orig 2010-05-18 11:22:18.000000000 -0700
945 +++ xpdf/SplashFontFile.cc      2010-05-18 11:22:18.000000000 -0700
946 @@ -11,9 +11,7 @@
947  #endif
948  
949  #include <stdio.h>
950 -#ifndef WIN32
951 -#  include <unistd.h>
952 -#endif
953 +#include <unistd.h>
954  #include "GString.h"
955  #include "SplashFontFile.h"
956  #include "SplashFontFileID.h"
957 --- xpdf/SplashOutputDev.cc.orig        2010-05-18 11:22:18.000000000 -0700
958 +++ xpdf/SplashOutputDev.cc     2010-05-18 11:22:18.000000000 -0700
959 @@ -13,6 +13,7 @@
960  #endif
961  
962  #include <string.h>
963 +#include <unistd.h>
964  #include <math.h>
965  #include "gfile.h"
966  #include "GlobalParams.h"
967 @@ -702,7 +703,7 @@
968    nT3Fonts = 0;
969  }
970  
971 -void SplashOutputDev::startPage(int pageNum, GfxState *state) {
972 +void SplashOutputDev::startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2) {
973    int w, h;
974    double *ctm;
975    SplashCoord mat[6];
976 @@ -2646,9 +2647,9 @@
977  
978    softMask = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
979                               1, splashModeMono8, gFalse);
980 -  memset(softMask->getDataPtr(), 0,
981 -        softMask->getRowSize() * softMask->getHeight());
982 +  memset(softMask->getDataPtr(), 0x00, softMask->getRowSize()*softMask->getHeight());
983    p = softMask->getDataPtr() + ty * softMask->getRowSize() + tx;
984 +  if (tx<softMask->getWidth() && ty<softMask->getHeight())
985    for (y = 0; y < tBitmap->getHeight(); ++y) {
986      for (x = 0; x < tBitmap->getWidth(); ++x) {
987        tBitmap->getPixel(x, y, color);
988 --- xpdf/SplashOutputDev.h.orig 2010-05-18 11:22:18.000000000 -0700
989 +++ xpdf/SplashOutputDev.h      2010-05-18 11:22:18.000000000 -0700
990 @@ -70,7 +70,7 @@
991    //----- initialization and control
992  
993    // Start a page.
994 -  virtual void startPage(int pageNum, GfxState *state);
995 +  virtual void startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2);
996  
997    // End a page.
998    virtual void endPage();
999 @@ -196,6 +196,9 @@
1000    virtual void setVectorAntialias(GBool vaa);
1001  #endif
1002  
1003 +  void doUpdateFont(GfxState *state);
1004 +  
1005 +  SplashPath *convertPath(GfxState *state, GfxPath *path);
1006  private:
1007  
1008    void setupScreenParams(double hDPI, double vDPI);
1009 @@ -204,8 +207,6 @@
1010  #else
1011    SplashPattern *getColor(GfxGray gray, GfxRGB *rgb);
1012  #endif
1013 -  SplashPath *convertPath(GfxState *state, GfxPath *path);
1014 -  void doUpdateFont(GfxState *state);
1015    void drawType3Glyph(T3FontCache *t3Font,
1016                       T3FontCacheTag *tag, Guchar *data);
1017    static GBool imageMaskSrc(void *data, SplashColorPtr line);
1018 --- xpdf/SplashScreen.cc.orig   2010-05-18 11:22:18.000000000 -0700
1019 +++ xpdf/SplashScreen.cc        2010-05-18 11:22:18.000000000 -0700
1020 @@ -363,6 +363,8 @@
1021  int SplashScreen::test(int x, int y, Guchar value) {
1022    int xx, yy;
1023  
1024 +  return 1;
1025 +
1026    if (value < minVal) {
1027      return 0;
1028    }
1029 --- xpdf/SplashXPathScanner.cc.orig     2010-05-18 11:22:18.000000000 -0700
1030 +++ xpdf/SplashXPathScanner.cc  2010-05-18 11:22:18.000000000 -0700
1031 @@ -394,10 +394,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 @@ -417,10 +417,10 @@
1045         *p++ &= mask;
1046         xx = (xx & ~7) + 8;
1047        }
1048 -      for (; xx + 7 <= xx0; xx += 8) {
1049 +      for (; xx + 7 < xx0; xx += 8) {
1050         *p++ = 0x00;
1051        }
1052 -      if (xx <= xx0) {
1053 +      if (xx < xx0) {
1054         *p &= 0xff >> (xx0 & 7);
1055        }
1056      }
1057 --- xpdf/Stream.cc.orig 2010-05-18 11:22:18.000000000 -0700
1058 +++ xpdf/Stream.cc      2010-05-18 11:22:18.000000000 -0700
1059 @@ -18,6 +18,8 @@
1060  #include <limits.h>
1061  #ifndef WIN32
1062  #include <unistd.h>
1063 +#else
1064 +extern "C" int unlink(char *filename);
1065  #endif
1066  #include <string.h>
1067  #include <ctype.h>
1068 @@ -2456,6 +2460,9 @@
1069    // check for an EOB run
1070    if (eobRun > 0) {
1071      while (i <= scanInfo.lastCoeff) {
1072 +      if(i>=64) {
1073 +         return gFalse;
1074 +      }
1075        j = dctZigZag[i++];
1076        if (data[j] != 0) {
1077         if ((bit = readBit()) == EOF) {
1078 @@ -2480,6 +2487,9 @@
1079      if (c == 0xf0) {
1080        k = 0;
1081        while (k < 16) {
1082 +        if(i>=64) {
1083 +         return gFalse;
1084 +       }
1085         j = dctZigZag[i++];
1086         if (data[j] == 0) {
1087           ++k;
1088 @@ -2505,6 +2515,9 @@
1089        }
1090        eobRun += 1 << j;
1091        while (i <= scanInfo.lastCoeff) {
1092 +       if(i>=64) {
1093 +         return gFalse;
1094 +       }
1095         j = dctZigZag[i++];
1096         if (data[j] != 0) {
1097           if ((bit = readBit()) == EOF) {
1098 @@ -2527,6 +2540,9 @@
1099        }
1100        k = 0;
1101        do {
1102 +       if(i>=64) {
1103 +         return gFalse;
1104 +       }
1105         j = dctZigZag[i++];
1106         while (data[j] != 0) {
1107           if ((bit = readBit()) == EOF) {
1108 @@ -2535,6 +2551,9 @@
1109           if (bit) {
1110             data[j] += 1 << scanInfo.al;
1111           }
1112 +         if(i>=64) {
1113 +           return gFalse;
1114 +         }
1115           j = dctZigZag[i++];
1116         }
1117         ++k;
1118 --- xpdf/Stream.h.orig  2010-05-18 11:22:18.000000000 -0700
1119 +++ xpdf/Stream.h       2010-05-18 11:22:18.000000000 -0700
1120 @@ -41,7 +41,8 @@
1121    streamCSNone,
1122    streamCSDeviceGray,
1123    streamCSDeviceRGB,
1124 -  streamCSDeviceCMYK
1125 +  streamCSDeviceCMYK,
1126 +  streamCSDeviceRGBX
1127  };
1128  
1129  //------------------------------------------------------------------------
1130 --- xpdf/TextOutputDev.cc.orig  2010-05-18 11:22:18.000000000 -0700
1131 +++ xpdf/TextOutputDev.cc       2010-05-18 11:22:18.000000000 -0700
1132 @@ -3877,7 +3877,7 @@
1133    }
1134  }
1135  
1136 -void TextOutputDev::startPage(int pageNum, GfxState *state) {
1137 +void TextOutputDev::startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2) {
1138    text->startPage(state);
1139  }
1140  
1141 --- xpdf/TextOutputDev.h.orig   2010-05-18 11:22:18.000000000 -0700
1142 +++ xpdf/TextOutputDev.h        2010-05-18 11:22:18.000000000 -0700
1143 @@ -170,6 +170,7 @@
1144    friend class TextFlow;
1145    friend class TextWordList;
1146    friend class TextPage;
1147 +  friend class XMLOutputDev;
1148  };
1149  
1150  //------------------------------------------------------------------------
1151 @@ -578,7 +579,7 @@
1152    //----- initialization and control
1153  
1154    // Start a page.
1155 -  virtual void startPage(int pageNum, GfxState *state);
1156 +  virtual void startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2);
1157  
1158    // End a page.
1159    virtual void endPage();
1160 --- xpdf/gfile.cc.orig  2010-05-18 11:22:18.000000000 -0700
1161 +++ xpdf/gfile.cc       2010-05-18 11:22:18.000000000 -0700
1162 @@ -439,6 +439,52 @@
1163  #endif
1164  }
1165  
1166 +static char* getTempDir()
1167 +{
1168 +#ifdef WIN32
1169 +    char*dir = getenv("TMP");
1170 +    if(!dir) dir = getenv("TEMP");
1171 +    if(!dir) dir = getenv("tmp");
1172 +    if(!dir) dir = getenv("temp");
1173 +    if(!dir) dir = "C:\\";
1174 +#else
1175 +    char* dir = "/tmp/";
1176 +#endif
1177 +    return dir;
1178 +}
1179 +
1180 +char* mktmpname(char*ptr) {
1181 +    static char tmpbuf[128];
1182 +    char*dir = getTempDir();
1183 +    int l = strlen(dir);
1184 +    char*sep = "";
1185 +    if(!ptr)
1186 +       ptr = tmpbuf;
1187 +    if(l && dir[l-1]!='/' && dir[l-1]!='\\') {
1188 +#ifdef WIN32
1189 +       sep = "\\";
1190 +#else
1191 +       sep = "/";
1192 +#endif
1193 +    }
1194 +
1195 + //   used to be mktemp. This does remove the warnings, but
1196 + //   It's not exactly an improvement.
1197 +#ifdef HAVE_LRAND48
1198 +    sprintf(ptr, "%s%s%08x%08x",dir,sep,(unsigned int)lrand48(),(unsigned int)lrand48());
1199 +#else
1200 +#   ifdef HAVE_RAND
1201 +       sprintf(ptr, "%s%s%08x%08x",dir,sep,rand(),rand());
1202 +#   else
1203 +       static int count = 1;
1204 +       sprintf(ptr, "%s%s%08x%04x%04x",dir,sep,time(0),(unsigned int)tmpbuf^((unsigned int)tmpbuf)>>16,count);
1205 +       count ++;
1206 +#   endif
1207 +#endif
1208 +     return ptr;
1209 +}
1210 +
1211 +
1212  GBool openTempFile(GString **name, FILE **f, char *mode, char *ext) {
1213  #if defined(WIN32)
1214    //---------- Win32 ----------
1215 @@ -460,7 +506,7 @@
1216    s->append("x");
1217    t = (int)time(NULL);
1218    for (i = 0; i < 1000; ++i) {
1219 -    sprintf(buf, "%d", t + i);
1220 +    sprintf(buf, "%08x-%08x", t + i, GetCurrentThreadId());
1221      s2 = s->copy()->append(buf);
1222      if (ext) {
1223        s2->append(ext);
1224 @@ -468,8 +514,7 @@
1225      if (!(f2 = fopen(s2->getCString(), "r"))) {
1226        if (!(f2 = fopen(s2->getCString(), mode))) {
1227         delete s2;
1228 -       delete s;
1229 -       return gFalse;
1230 +        continue;
1231        }
1232        *name = s2;
1233        *f = f2;
1234 @@ -479,6 +524,7 @@
1235      fclose(f2);
1236      delete s2;
1237    }
1238 +  fprintf(stderr, "Couldn't create temporary file\n");
1239    delete s;
1240    return gFalse;
1241  #elif defined(VMS) || defined(__EMX__) || defined(ACORN) || defined(MACOS)
1242 @@ -489,7 +535,7 @@
1243    // with this file name after the tmpnam call and before the fopen
1244    // call.  I will happily accept fixes to this function for non-Unix
1245    // OSs.
1246 -  if (!(s = tmpnam(NULL))) {
1247 +  if (!(s = mktmpname(NULL))) {
1248      return gFalse;
1249    }
1250    *name = new GString(s);
1251 @@ -516,7 +562,7 @@
1252      (*name)->append("/XXXXXX")->append(ext);
1253      fd = mkstemps((*name)->getCString(), strlen(ext));
1254  #else
1255 -    if (!(s = tmpnam(NULL))) {
1256 +    if (!(s = mktmpname(NULL))) {
1257        return gFalse;
1258      }
1259      *name = new GString(s);
1260 @@ -533,7 +579,7 @@
1261      (*name)->append("/XXXXXX");
1262      fd = mkstemp((*name)->getCString());
1263  #else // HAVE_MKSTEMP
1264 -    if (!(s = tmpnam(NULL))) {
1265 +    if (!(s = mktmpname(NULL))) {
1266        return gFalse;
1267      }
1268      *name = new GString(s);
1269 --- xpdf/gfile.h.orig   2010-05-18 11:22:18.000000000 -0700
1270 +++ xpdf/gfile.h        2010-05-18 11:22:18.000000000 -0700
1271 @@ -58,6 +58,9 @@
1272  // Get current directory.
1273  extern GString *getCurrentDir();
1274  
1275 +/* create a temporary filename */
1276 +char* mktmpname(char*ptr);
1277 +
1278  // Append a file name to a path string.  <path> may be an empty
1279  // string, denoting the current directory).  Returns <path>.
1280  extern GString *appendToPath(GString *path, char *fileName);
1281 --- xpdf/JBIG2Stream.cc.orig    2010-05-18 11:33:21.000000000 -0700
1282 +++ xpdf/JBIG2Stream.cc 2010-06-03 16:55:03.000000000 -0700
1283 @@ -6,7 +6,24 @@
1284  //
1285  //========================================================================
1286  
1287 -#include <aconf.h>
1288 +//========================================================================
1289 +//
1290 +// Modified under the Poppler project - http://poppler.freedesktop.org
1291 +//
1292 +// All changes made under the Poppler project to this file are licensed
1293 +// under GPL version 2 or later
1294 +//
1295 +// Copyright (C) 2006 Raj Kumar <rkumar@archive.org>
1296 +// Copyright (C) 2006 Paul Walmsley <paul@booyaka.com>
1297 +// Copyright (C) 2006-2009 Albert Astals Cid <aacid@kde.org>
1298 +// Copyright (C) 2009 David Benjamin <davidben@mit.edu>
1299 +//
1300 +// To see a description of the changes please see the Changelog file that
1301 +// came with your tarball or type make ChangeLog if you are building from git
1302 +//
1303 +//========================================================================
1304 +
1305 +#include <config.h>
1306  
1307  #ifdef USE_GCC_PRAGMAS
1308  #pragma implementation
1309 @@ -24,8 +41,8 @@
1310  
1311  //------------------------------------------------------------------------
1312  
1313 -static int contextSize[4] = { 16, 13, 10, 10 };
1314 -static int refContextSize[2] = { 13, 10 };
1315 +static const int contextSize[4] = { 16, 13, 10, 10 };
1316 +static const int refContextSize[2] = { 13, 10 };
1317  
1318  //------------------------------------------------------------------------
1319  // JBIG2HuffmanTable
1320 @@ -42,7 +59,7 @@
1321    Guint prefix;
1322  };
1323  
1324 -JBIG2HuffmanTable huffTableA[] = {
1325 +static JBIG2HuffmanTable huffTableA[] = {
1326    {     0, 1,  4,              0x000 },
1327    {    16, 2,  8,              0x002 },
1328    {   272, 3, 16,              0x006 },
1329 @@ -50,7 +67,7 @@
1330    {     0, 0, jbig2HuffmanEOT, 0     }
1331  };
1332  
1333 -JBIG2HuffmanTable huffTableB[] = {
1334 +static JBIG2HuffmanTable huffTableB[] = {
1335    {     0, 1,  0,              0x000 },
1336    {     1, 2,  0,              0x002 },
1337    {     2, 3,  0,              0x006 },
1338 @@ -61,7 +78,7 @@
1339    {     0, 0, jbig2HuffmanEOT, 0     }
1340  };
1341  
1342 -JBIG2HuffmanTable huffTableC[] = {
1343 +static JBIG2HuffmanTable huffTableC[] = {
1344    {     0, 1,  0,              0x000 },
1345    {     1, 2,  0,              0x002 },
1346    {     2, 3,  0,              0x006 },
1347 @@ -74,7 +91,7 @@
1348    {     0, 0, jbig2HuffmanEOT, 0     }
1349  };
1350  
1351 -JBIG2HuffmanTable huffTableD[] = {
1352 +static JBIG2HuffmanTable huffTableD[] = {
1353    {     1, 1,  0,              0x000 },
1354    {     2, 2,  0,              0x002 },
1355    {     3, 3,  0,              0x006 },
1356 @@ -84,7 +101,7 @@
1357    {     0, 0, jbig2HuffmanEOT, 0     }
1358  };
1359  
1360 -JBIG2HuffmanTable huffTableE[] = {
1361 +static JBIG2HuffmanTable huffTableE[] = {
1362    {     1, 1,  0,              0x000 },
1363    {     2, 2,  0,              0x002 },
1364    {     3, 3,  0,              0x006 },
1365 @@ -96,7 +113,7 @@
1366    {     0, 0, jbig2HuffmanEOT, 0     }
1367  };
1368  
1369 -JBIG2HuffmanTable huffTableF[] = {
1370 +static JBIG2HuffmanTable huffTableF[] = {
1371    {     0, 2,  7,              0x000 },
1372    {   128, 3,  7,              0x002 },
1373    {   256, 3,  8,              0x003 },
1374 @@ -114,7 +131,7 @@
1375    {     0, 0, jbig2HuffmanEOT, 0     }
1376  };
1377  
1378 -JBIG2HuffmanTable huffTableG[] = {
1379 +static JBIG2HuffmanTable huffTableG[] = {
1380    {  -512, 3,  8,              0x000 },
1381    {   256, 3,  8,              0x001 },
1382    {   512, 3,  9,              0x002 },
1383 @@ -133,7 +150,7 @@
1384    {     0, 0, jbig2HuffmanEOT, 0     }
1385  };
1386  
1387 -JBIG2HuffmanTable huffTableH[] = {
1388 +static JBIG2HuffmanTable huffTableH[] = {
1389    {     0, 2,  1,              0x000 },
1390    {     0, 2, jbig2HuffmanOOB, 0x001 },
1391    {     4, 3,  4,              0x004 },
1392 @@ -158,7 +175,7 @@
1393    {     0, 0, jbig2HuffmanEOT, 0     }
1394  };
1395  
1396 -JBIG2HuffmanTable huffTableI[] = {
1397 +static JBIG2HuffmanTable huffTableI[] = {
1398    {     0, 2, jbig2HuffmanOOB, 0x000 },
1399    {    -1, 3,  1,              0x002 },
1400    {     1, 3,  1,              0x003 },
1401 @@ -184,7 +201,7 @@
1402    {     0, 0, jbig2HuffmanEOT, 0     }
1403  };
1404  
1405 -JBIG2HuffmanTable huffTableJ[] = {
1406 +static JBIG2HuffmanTable huffTableJ[] = {
1407    {    -2, 2,  2,              0x000 },
1408    {     6, 2,  6,              0x001 },
1409    {     0, 2, jbig2HuffmanOOB, 0x002 },
1410 @@ -209,7 +226,7 @@
1411    {     0, 0, jbig2HuffmanEOT, 0     }
1412  };
1413  
1414 -JBIG2HuffmanTable huffTableK[] = {
1415 +static JBIG2HuffmanTable huffTableK[] = {
1416    {     1, 1,  0,              0x000 },
1417    {     2, 2,  1,              0x002 },
1418    {     4, 4,  0,              0x00c },
1419 @@ -226,7 +243,7 @@
1420    {     0, 0, jbig2HuffmanEOT, 0     }
1421  };
1422  
1423 -JBIG2HuffmanTable huffTableL[] = {
1424 +static JBIG2HuffmanTable huffTableL[] = {
1425    {     1, 1,  0,              0x000 },
1426    {     2, 2,  0,              0x002 },
1427    {     3, 3,  1,              0x006 },
1428 @@ -243,7 +260,7 @@
1429    {     0, 0, jbig2HuffmanEOT, 0     }
1430  };
1431  
1432 -JBIG2HuffmanTable huffTableM[] = {
1433 +static JBIG2HuffmanTable huffTableM[] = {
1434    {     1, 1,  0,              0x000 },
1435    {     2, 3,  0,              0x004 },
1436    {     7, 3,  3,              0x005 },
1437 @@ -260,7 +277,7 @@
1438    {     0, 0, jbig2HuffmanEOT, 0     }
1439  };
1440  
1441 -JBIG2HuffmanTable huffTableN[] = {
1442 +static JBIG2HuffmanTable huffTableN[] = {
1443    {     0, 1,  0,              0x000 },
1444    {    -2, 3,  0,              0x004 },
1445    {    -1, 3,  0,              0x005 },
1446 @@ -269,7 +286,7 @@
1447    {     0, 0, jbig2HuffmanEOT, 0     }
1448  };
1449  
1450 -JBIG2HuffmanTable huffTableO[] = {
1451 +static JBIG2HuffmanTable huffTableO[] = {
1452    {     0, 1,  0,              0x000 },
1453    {    -1, 3,  0,              0x004 },
1454    {     1, 3,  0,              0x005 },
1455 @@ -473,7 +490,7 @@
1456  }
1457  
1458  int JBIG2MMRDecoder::get2DCode() {
1459 -  CCITTCode *p;
1460 +  const CCITTCode *p;
1461  
1462    if (bufLen == 0) {
1463      buf = str->getChar() & 0xff;
1464 @@ -500,7 +517,7 @@
1465  }
1466  
1467  int JBIG2MMRDecoder::getWhiteCode() {
1468 -  CCITTCode *p;
1469 +  const CCITTCode *p;
1470    Guint code;
1471  
1472    if (bufLen == 0) {
1473 @@ -543,7 +560,7 @@
1474  }
1475  
1476  int JBIG2MMRDecoder::getBlackCode() {
1477 -  CCITTCode *p;
1478 +  const CCITTCode *p;
1479    Guint code;
1480  
1481    if (bufLen == 0) {
1482 @@ -670,6 +687,7 @@
1483    void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
1484    Guchar *getDataPtr() { return data; }
1485    int getDataSize() { return h * line; }
1486 +  GBool isOk() { return data != NULL; }
1487  
1488  private:
1489  
1490 @@ -685,10 +703,11 @@
1491    w = wA;
1492    h = hA;
1493    line = (wA + 7) >> 3;
1494 +
1495    if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
1496 -    // force a call to gmalloc(-1), which will throw an exception
1497 -    h = -1;
1498 -    line = 2;
1499 +    error(-1, "invalid width/height");
1500 +    data = NULL;
1501 +    return;
1502    }
1503    // need to allocate one extra guard byte for use in combine()
1504    data = (Guchar *)gmalloc(h * line + 1);
1505 @@ -701,10 +720,11 @@
1506    w = bitmap->w;
1507    h = bitmap->h;
1508    line = bitmap->line;
1509 +
1510    if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
1511 -    // force a call to gmalloc(-1), which will throw an exception
1512 -    h = -1;
1513 -    line = 2;
1514 +    error(-1, "invalid width/height");
1515 +    data = NULL;
1516 +    return;
1517    }
1518    // need to allocate one extra guard byte for use in combine()
1519    data = (Guchar *)gmalloc(h * line + 1);
1520 @@ -735,6 +755,9 @@
1521  
1522  void JBIG2Bitmap::expand(int newH, Guint pixel) {
1523    if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
1524 +    error(-1, "invalid width/height");
1525 +    gfree(data);
1526 +    data = NULL;
1527      return;
1528    }
1529    // need to allocate one extra guard byte for use in combine()
1530 @@ -1002,6 +1025,7 @@
1531    Guint getSize() { return size; }
1532    void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1533    JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1534 +  GBool isOk() { return bitmaps != NULL; }
1535    void setGenericRegionStats(JArithmeticDecoderStats *stats)
1536      { genericRegionStats = stats; }
1537    void setRefinementRegionStats(JArithmeticDecoderStats *stats)
1538 @@ -1022,13 +1046,9 @@
1539  JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
1540    JBIG2Segment(segNumA)
1541  {
1542 -  Guint i;
1543 -
1544    size = sizeA;
1545    bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
1546 -  for (i = 0; i < size; ++i) {
1547 -    bitmaps[i] = NULL;
1548 -  }
1549 +  if (!bitmaps) size = 0;
1550    genericRegionStats = NULL;
1551    refinementRegionStats = NULL;
1552  }
1553 @@ -1037,9 +1057,7 @@
1554    Guint i;
1555  
1556    for (i = 0; i < size; ++i) {
1557 -    if (bitmaps[i]) {
1558 -      delete bitmaps[i];
1559 -    }
1560 +    delete bitmaps[i];
1561    }
1562    gfree(bitmaps);
1563    if (genericRegionStats) {
1564 @@ -1247,6 +1265,7 @@
1565    Guint segNum, segFlags, segType, page, segLength;
1566    Guint refFlags, nRefSegs;
1567    Guint *refSegs;
1568 +  int segDataPos;
1569    int c1, c2, c3;
1570    Guint i;
1571  
1572 @@ -1314,6 +1333,9 @@
1573        goto eofError2;
1574      }
1575  
1576 +    // keep track of the start of the segment data 
1577 +    segDataPos = getPos();
1578 +
1579      // check for missing page information segment
1580      if (!pageBitmap && ((segType >= 4 && segType <= 7) ||
1581                         (segType >= 20 && segType <= 43))) {
1582 @@ -1398,6 +1420,45 @@
1583        break;
1584      }
1585  
1586 +    // Make sure the segment handler read all of the bytes in the 
1587 +    // segment data, unless this segment is marked as having an
1588 +    // unknown length (section 7.2.7 of the JBIG2 Final Committee Draft)
1589 +
1590 +    if (segLength != 0xffffffff) {
1591 +
1592 +      int segExtraBytes = segDataPos + segLength - getPos();
1593 +      if (segExtraBytes > 0) {
1594 +
1595 +       // If we didn't read all of the bytes in the segment data,
1596 +       // indicate an error, and throw away the rest of the data.
1597 +       
1598 +       // v.3.1.01.13 of the LuraTech PDF Compressor Server will
1599 +       // sometimes generate an extraneous NULL byte at the end of
1600 +       // arithmetic-coded symbol dictionary segments when numNewSyms
1601 +       // == 0.  Segments like this often occur for blank pages.
1602 +       
1603 +       error(getPos(), "%d extraneous byte%s after segment",
1604 +             segExtraBytes, (segExtraBytes > 1) ? "s" : "");
1605 +       
1606 +       // Burn through the remaining bytes -- inefficient, but
1607 +       // hopefully we're not doing this much
1608 +       
1609 +       int trash;
1610 +       for (int i = segExtraBytes; i > 0; i--) {
1611 +         readByte(&trash);
1612 +       }
1613 +       
1614 +      } else if (segExtraBytes < 0) {
1615 +       
1616 +       // If we read more bytes than we should have, according to the 
1617 +       // segment length field, note an error.
1618 +       
1619 +       error(getPos(), "Previous segment handler read too many bytes");
1620 +       
1621 +      }
1622 +
1623 +    }
1624 +    
1625      gfree(refSegs);
1626    }
1627  
1628 @@ -1493,6 +1554,9 @@
1629    codeTables = new GList();
1630    numInputSyms = 0;
1631    for (i = 0; i < nRefSegs; ++i) {
1632 +    // This is need by bug 12014, returning gFalse makes it not crash
1633 +    // but we end up with a empty page while acroread is able to render
1634 +    // part of it
1635      if ((seg = findSegment(refSegs[i]))) {
1636        if (seg->getType() == jbig2SegSymbolDict) {
1637         j = ((JBIG2SymbolDict *)seg)->getSize();
1638 @@ -1503,8 +1567,11 @@
1639         }
1640         numInputSyms += j;
1641        } else if (seg->getType() == jbig2SegCodeTable) {
1642 -       codeTables->append(seg);
1643 +        codeTables->append(seg);
1644        }
1645 +    } else {
1646 +      delete codeTables;
1647 +      return gFalse;
1648      }
1649    }
1650    if (numInputSyms > UINT_MAX - numNewSyms) {
1651 @@ -1530,12 +1600,11 @@
1652    k = 0;
1653    inputSymbolDict = NULL;
1654    for (i = 0; i < nRefSegs; ++i) {
1655 -    if ((seg = findSegment(refSegs[i]))) {
1656 -      if (seg->getType() == jbig2SegSymbolDict) {
1657 -       inputSymbolDict = (JBIG2SymbolDict *)seg;
1658 -       for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1659 -         bitmaps[k++] = inputSymbolDict->getBitmap(j);
1660 -       }
1661 +    seg = findSegment(refSegs[i]);
1662 +    if (seg != NULL && seg->getType() == jbig2SegSymbolDict) {
1663 +      inputSymbolDict = (JBIG2SymbolDict *)seg;
1664 +      for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1665 +       bitmaps[k++] = inputSymbolDict->getBitmap(j);
1666        }
1667      }
1668    }
1669 @@ -1753,6 +1822,10 @@
1670  
1671    // create the symbol dict object
1672    symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1673 +  if (!symbolDict->isOk()) {
1674 +    delete symbolDict;
1675 +    goto syntaxError;
1676 +  }
1677  
1678    // exported symbol list
1679    i = j = 0;
1680 @@ -1766,6 +1839,7 @@
1681      if (i + run > numInputSyms + numNewSyms ||
1682         (ex && j + run > numExSyms)) {
1683        error(getPos(), "Too many exported symbols in JBIG2 symbol dictionary");
1684 +      for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
1685        delete symbolDict;
1686        goto syntaxError;
1687      }
1688 @@ -1780,6 +1854,7 @@
1689    }
1690    if (j != numExSyms) {
1691      error(getPos(), "Too few symbols in JBIG2 symbol dictionary");
1692 +    for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
1693      delete symbolDict;
1694      goto syntaxError;
1695    }
1696 @@ -2095,18 +2170,20 @@
1697  
1698    gfree(syms);
1699  
1700 -  // combine the region bitmap into the page bitmap
1701 -  if (imm) {
1702 -    if (pageH == 0xffffffff && y + h > curPageH) {
1703 -      pageBitmap->expand(y + h, pageDefPixel);
1704 -    }
1705 -    pageBitmap->combine(bitmap, x, y, extCombOp);
1706 -    delete bitmap;
1707 +  if (bitmap) {
1708 +    // combine the region bitmap into the page bitmap
1709 +    if (imm) {
1710 +      if (pageH == 0xffffffff && y + h > curPageH) {
1711 +        pageBitmap->expand(y + h, pageDefPixel);
1712 +      }
1713 +      pageBitmap->combine(bitmap, x, y, extCombOp);
1714 +      delete bitmap;
1715  
1716 -  // store the region bitmap
1717 -  } else {
1718 -    bitmap->setSegNum(segNum);
1719 -    segments->append(bitmap);
1720 +    // store the region bitmap
1721 +    } else {
1722 +      bitmap->setSegNum(segNum);
1723 +      segments->append(bitmap);
1724 +    }
1725    }
1726  
1727    // clean up the Huffman decoder
1728 @@ -2159,6 +2236,10 @@
1729  
1730    // allocate the bitmap
1731    bitmap = new JBIG2Bitmap(0, w, h);
1732 +  if (!bitmap->isOk()) {
1733 +    delete bitmap;
1734 +    return NULL;
1735 +  }
1736    if (defPixel) {
1737      bitmap->clearToOne();
1738    } else {
1739 @@ -2235,73 +2316,84 @@
1740           ri = 0;
1741         }
1742         if (ri) {
1743 +         GBool decodeSuccess;
1744           if (huff) {
1745 -           huffDecoder->decodeInt(&rdw, huffRDWTable);
1746 -           huffDecoder->decodeInt(&rdh, huffRDHTable);
1747 -           huffDecoder->decodeInt(&rdx, huffRDXTable);
1748 -           huffDecoder->decodeInt(&rdy, huffRDYTable);
1749 -           huffDecoder->decodeInt(&bmSize, huffRSizeTable);
1750 +           decodeSuccess = huffDecoder->decodeInt(&rdw, huffRDWTable);
1751 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdh, huffRDHTable);
1752 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdx, huffRDXTable);
1753 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdy, huffRDYTable);
1754 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&bmSize, huffRSizeTable);
1755             huffDecoder->reset();
1756             arithDecoder->start();
1757           } else {
1758 -           arithDecoder->decodeInt(&rdw, iardwStats);
1759 -           arithDecoder->decodeInt(&rdh, iardhStats);
1760 -           arithDecoder->decodeInt(&rdx, iardxStats);
1761 -           arithDecoder->decodeInt(&rdy, iardyStats);
1762 +           decodeSuccess = arithDecoder->decodeInt(&rdw, iardwStats);
1763 +           decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdh, iardhStats);
1764 +           decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdx, iardxStats);
1765 +           decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdy, iardyStats);
1766 +         }
1767 +         
1768 +         if (decodeSuccess && syms[symID])
1769 +         {
1770 +           refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
1771 +           refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
1772 +
1773 +           symbolBitmap =
1774 +             readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
1775 +                                         rdh + syms[symID]->getHeight(),
1776 +                                         templ, gFalse, syms[symID],
1777 +                                         refDX, refDY, atx, aty);
1778           }
1779 -         refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
1780 -         refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
1781 -
1782 -         symbolBitmap =
1783 -           readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
1784 -                                       rdh + syms[symID]->getHeight(),
1785 -                                       templ, gFalse, syms[symID],
1786 -                                       refDX, refDY, atx, aty);
1787           //~ do we need to use the bmSize value here (in Huffman mode)?
1788         } else {
1789           symbolBitmap = syms[symID];
1790         }
1791  
1792 -       // combine the symbol bitmap into the region bitmap
1793 -       //~ something is wrong here - refCorner shouldn't degenerate into
1794 -       //~   two cases
1795 -       bw = symbolBitmap->getWidth() - 1;
1796 -       bh = symbolBitmap->getHeight() - 1;
1797 -       if (transposed) {
1798 -         switch (refCorner) {
1799 -         case 0: // bottom left
1800 -           bitmap->combine(symbolBitmap, tt, s, combOp);
1801 -           break;
1802 -         case 1: // top left
1803 -           bitmap->combine(symbolBitmap, tt, s, combOp);
1804 -           break;
1805 -         case 2: // bottom right
1806 -           bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1807 -           break;
1808 -         case 3: // top right
1809 -           bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1810 -           break;
1811 +       if (symbolBitmap) {
1812 +         // combine the symbol bitmap into the region bitmap
1813 +         //~ something is wrong here - refCorner shouldn't degenerate into
1814 +         //~   two cases
1815 +         bw = symbolBitmap->getWidth() - 1;
1816 +         bh = symbolBitmap->getHeight() - 1;
1817 +         if (transposed) {
1818 +           switch (refCorner) {
1819 +           case 0: // bottom left
1820 +             bitmap->combine(symbolBitmap, tt, s, combOp);
1821 +             break;
1822 +           case 1: // top left
1823 +             bitmap->combine(symbolBitmap, tt, s, combOp);
1824 +             break;
1825 +           case 2: // bottom right
1826 +             bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1827 +             break;
1828 +           case 3: // top right
1829 +             bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1830 +             break;
1831 +           }
1832 +           s += bh;
1833 +         } else {
1834 +           switch (refCorner) {
1835 +           case 0: // bottom left
1836 +             bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1837 +             break;
1838 +           case 1: // top left
1839 +             bitmap->combine(symbolBitmap, s, tt, combOp);
1840 +             break;
1841 +           case 2: // bottom right
1842 +             bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1843 +             break;
1844 +           case 3: // top right
1845 +             bitmap->combine(symbolBitmap, s, tt, combOp);
1846 +             break;
1847 +           }
1848 +           s += bw;
1849           }
1850 -         s += bh;
1851 -       } else {
1852 -         switch (refCorner) {
1853 -         case 0: // bottom left
1854 -           bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1855 -           break;
1856 -         case 1: // top left
1857 -           bitmap->combine(symbolBitmap, s, tt, combOp);
1858 -           break;
1859 -         case 2: // bottom right
1860 -           bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1861 -           break;
1862 -         case 3: // top right
1863 -           bitmap->combine(symbolBitmap, s, tt, combOp);
1864 -           break;
1865 +         if (ri) {
1866 +           delete symbolBitmap;
1867           }
1868 -         s += bw;
1869 -       }
1870 -       if (ri) {
1871 -         delete symbolBitmap;
1872 +       } else {
1873 +         // NULL symbolBitmap only happens on error
1874 +         delete bitmap;
1875 +         return NULL;
1876         }
1877        }
1878  
1879 @@ -2431,11 +2523,12 @@
1880      error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
1881      return;
1882    }
1883 -  if (!(seg = findSegment(refSegs[0])) ||
1884 -      seg->getType() != jbig2SegPatternDict) {
1885 +  seg = findSegment(refSegs[0]);
1886 +  if (seg == NULL || seg->getType() != jbig2SegPatternDict) {
1887      error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
1888      return;
1889    }
1890 +
1891    patternDict = (JBIG2PatternDict *)seg;
1892    bpp = 0;
1893    i = 1;
1894 @@ -2591,6 +2684,8 @@
1895    // read the bitmap
1896    bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
1897                              NULL, atx, aty, mmr ? length - 18 : 0);
1898 +  if (!bitmap)
1899 +    return;
1900  
1901    // combine the region bitmap into the page bitmap
1902    if (imm) {
1903 @@ -2616,7 +2711,7 @@
1904                                       int *codingLine, int *a0i, int w) {
1905    if (a1 > codingLine[*a0i]) {
1906      if (a1 > w) {
1907 -      error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
1908 +      error(getPos(), "JBIG2 MMR row is wrong length (%d)", a1);
1909        a1 = w;
1910      }
1911      if ((*a0i & 1) ^ blackPixels) {
1912 @@ -2630,7 +2725,7 @@
1913                                          int *codingLine, int *a0i, int w) {
1914    if (a1 > codingLine[*a0i]) {
1915      if (a1 > w) {
1916 -      error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
1917 +      error(getPos(), "JBIG2 MMR row is wrong length (%d)", a1);
1918        a1 = w;
1919      }
1920      if ((*a0i & 1) ^ blackPixels) {
1921 @@ -2657,13 +2752,17 @@
1922    JBIG2Bitmap *bitmap;
1923    GBool ltp;
1924    Guint ltpCX, cx, cx0, cx1, cx2;
1925 -  JBIG2BitmapPtr cxPtr0, cxPtr1;
1926 -  JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3;
1927 +  JBIG2BitmapPtr cxPtr0 = {0}, cxPtr1 = {0};
1928 +  JBIG2BitmapPtr atPtr0 = {0}, atPtr1 = {0}, atPtr2 = {0}, atPtr3 = {0};
1929    int *refLine, *codingLine;
1930    int code1, code2, code3;
1931    int x, y, a0i, b1i, blackPixels, pix, i;
1932  
1933    bitmap = new JBIG2Bitmap(0, w, h);
1934 +  if (!bitmap->isOk()) {
1935 +    delete bitmap;
1936 +    return NULL;
1937 +  }
1938    bitmap->clearToZero();
1939  
1940    //----- MMR decode
1941 @@ -2682,7 +2781,7 @@
1942      // ---> max refLine size = w + 2
1943      codingLine = (int *)gmallocn(w + 1, sizeof(int));
1944      refLine = (int *)gmallocn(w + 2, sizeof(int));
1945 -    codingLine[0] = w;
1946 +    for (i = 0; i < w + 1; ++i) codingLine[i] = w;
1947  
1948      for (y = 0; y < h; ++y) {
1949  
1950 @@ -3093,8 +3192,8 @@
1951      return;
1952    }
1953    if (nRefSegs == 1) {
1954 -    if (!(seg = findSegment(refSegs[0])) ||
1955 -       seg->getType() != jbig2SegBitmap) {
1956 +    seg = findSegment(refSegs[0]);
1957 +    if (seg == NULL || seg->getType() != jbig2SegBitmap) {
1958        error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
1959        return;
1960      }
1961 @@ -3143,11 +3242,24 @@
1962    JBIG2Bitmap *bitmap;
1963    GBool ltp;
1964    Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
1965 -  JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
1966 -  JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
1967 +  JBIG2BitmapPtr cxPtr0 = {0};
1968 +  JBIG2BitmapPtr cxPtr1 = {0};
1969 +  JBIG2BitmapPtr cxPtr2 = {0};
1970 +  JBIG2BitmapPtr cxPtr3 = {0};
1971 +  JBIG2BitmapPtr cxPtr4 = {0};
1972 +  JBIG2BitmapPtr cxPtr5 = {0};
1973 +  JBIG2BitmapPtr cxPtr6 = {0};
1974 +  JBIG2BitmapPtr tpgrCXPtr0 = {0};
1975 +  JBIG2BitmapPtr tpgrCXPtr1 = {0};
1976 +  JBIG2BitmapPtr tpgrCXPtr2 = {0};
1977    int x, y, pix;
1978  
1979    bitmap = new JBIG2Bitmap(0, w, h);
1980 +  if (!bitmap->isOk())
1981 +  {
1982 +    delete bitmap;
1983 +    return NULL;
1984 +  }
1985    bitmap->clearToZero();
1986  
1987    // set up the typical row context
1988 @@ -3332,6 +3444,12 @@
1989    }
1990    pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
1991  
1992 +  if (!pageBitmap->isOk()) {
1993 +    delete pageBitmap;
1994 +    pageBitmap = NULL;
1995 +    return;
1996 +  }
1997 +  
1998    // default pixel value
1999    if (pageDefPixel) {
2000      pageBitmap->clearToOne();