e829b2e5eefef437f079453a3f47b6a09ed18cc6
[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 --- xpdf/Stream.h.orig  2010-05-18 11:22:18.000000000 -0700
1056 +++ xpdf/Stream.h       2010-05-18 11:22:18.000000000 -0700
1057 @@ -41,7 +41,8 @@
1058    streamCSNone,
1059    streamCSDeviceGray,
1060    streamCSDeviceRGB,
1061 -  streamCSDeviceCMYK
1062 +  streamCSDeviceCMYK,
1063 +  streamCSDeviceRGBX
1064  };
1065  
1066  //------------------------------------------------------------------------
1067 --- xpdf/TextOutputDev.cc.orig  2010-05-18 11:22:18.000000000 -0700
1068 +++ xpdf/TextOutputDev.cc       2010-05-18 11:22:18.000000000 -0700
1069 @@ -3877,7 +3877,7 @@
1070    }
1071  }
1072  
1073 -void TextOutputDev::startPage(int pageNum, GfxState *state) {
1074 +void TextOutputDev::startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2) {
1075    text->startPage(state);
1076  }
1077  
1078 --- xpdf/TextOutputDev.h.orig   2010-05-18 11:22:18.000000000 -0700
1079 +++ xpdf/TextOutputDev.h        2010-05-18 11:22:18.000000000 -0700
1080 @@ -170,6 +170,7 @@
1081    friend class TextFlow;
1082    friend class TextWordList;
1083    friend class TextPage;
1084 +  friend class XMLOutputDev;
1085  };
1086  
1087  //------------------------------------------------------------------------
1088 @@ -578,7 +579,7 @@
1089    //----- initialization and control
1090  
1091    // Start a page.
1092 -  virtual void startPage(int pageNum, GfxState *state);
1093 +  virtual void startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2);
1094  
1095    // End a page.
1096    virtual void endPage();
1097 --- xpdf/gfile.cc.orig  2010-05-18 11:22:18.000000000 -0700
1098 +++ xpdf/gfile.cc       2010-05-18 11:22:18.000000000 -0700
1099 @@ -439,6 +439,52 @@
1100  #endif
1101  }
1102  
1103 +static char* getTempDir()
1104 +{
1105 +#ifdef WIN32
1106 +    char*dir = getenv("TMP");
1107 +    if(!dir) dir = getenv("TEMP");
1108 +    if(!dir) dir = getenv("tmp");
1109 +    if(!dir) dir = getenv("temp");
1110 +    if(!dir) dir = "C:\\";
1111 +#else
1112 +    char* dir = "/tmp/";
1113 +#endif
1114 +    return dir;
1115 +}
1116 +
1117 +char* mktmpname(char*ptr) {
1118 +    static char tmpbuf[128];
1119 +    char*dir = getTempDir();
1120 +    int l = strlen(dir);
1121 +    char*sep = "";
1122 +    if(!ptr)
1123 +       ptr = tmpbuf;
1124 +    if(l && dir[l-1]!='/' && dir[l-1]!='\\') {
1125 +#ifdef WIN32
1126 +       sep = "\\";
1127 +#else
1128 +       sep = "/";
1129 +#endif
1130 +    }
1131 +
1132 + //   used to be mktemp. This does remove the warnings, but
1133 + //   It's not exactly an improvement.
1134 +#ifdef HAVE_LRAND48
1135 +    sprintf(ptr, "%s%s%08x%08x",dir,sep,(unsigned int)lrand48(),(unsigned int)lrand48());
1136 +#else
1137 +#   ifdef HAVE_RAND
1138 +       sprintf(ptr, "%s%s%08x%08x",dir,sep,rand(),rand());
1139 +#   else
1140 +       static int count = 1;
1141 +       sprintf(ptr, "%s%s%08x%04x%04x",dir,sep,time(0),(unsigned int)tmpbuf^((unsigned int)tmpbuf)>>16,count);
1142 +       count ++;
1143 +#   endif
1144 +#endif
1145 +     return ptr;
1146 +}
1147 +
1148 +
1149  GBool openTempFile(GString **name, FILE **f, char *mode, char *ext) {
1150  #if defined(WIN32)
1151    //---------- Win32 ----------
1152 @@ -460,7 +506,7 @@
1153    s->append("x");
1154    t = (int)time(NULL);
1155    for (i = 0; i < 1000; ++i) {
1156 -    sprintf(buf, "%d", t + i);
1157 +    sprintf(buf, "%08x-%08x", t + i, GetCurrentThreadId());
1158      s2 = s->copy()->append(buf);
1159      if (ext) {
1160        s2->append(ext);
1161 @@ -468,8 +514,7 @@
1162      if (!(f2 = fopen(s2->getCString(), "r"))) {
1163        if (!(f2 = fopen(s2->getCString(), mode))) {
1164         delete s2;
1165 -       delete s;
1166 -       return gFalse;
1167 +        continue;
1168        }
1169        *name = s2;
1170        *f = f2;
1171 @@ -479,6 +524,7 @@
1172      fclose(f2);
1173      delete s2;
1174    }
1175 +  fprintf(stderr, "Couldn't create temporary file\n");
1176    delete s;
1177    return gFalse;
1178  #elif defined(VMS) || defined(__EMX__) || defined(ACORN) || defined(MACOS)
1179 @@ -489,7 +535,7 @@
1180    // with this file name after the tmpnam call and before the fopen
1181    // call.  I will happily accept fixes to this function for non-Unix
1182    // OSs.
1183 -  if (!(s = tmpnam(NULL))) {
1184 +  if (!(s = mktmpname(NULL))) {
1185      return gFalse;
1186    }
1187    *name = new GString(s);
1188 @@ -516,7 +562,7 @@
1189      (*name)->append("/XXXXXX")->append(ext);
1190      fd = mkstemps((*name)->getCString(), strlen(ext));
1191  #else
1192 -    if (!(s = tmpnam(NULL))) {
1193 +    if (!(s = mktmpname(NULL))) {
1194        return gFalse;
1195      }
1196      *name = new GString(s);
1197 @@ -533,7 +579,7 @@
1198      (*name)->append("/XXXXXX");
1199      fd = mkstemp((*name)->getCString());
1200  #else // HAVE_MKSTEMP
1201 -    if (!(s = tmpnam(NULL))) {
1202 +    if (!(s = mktmpname(NULL))) {
1203        return gFalse;
1204      }
1205      *name = new GString(s);
1206 --- xpdf/gfile.h.orig   2010-05-18 11:22:18.000000000 -0700
1207 +++ xpdf/gfile.h        2010-05-18 11:22:18.000000000 -0700
1208 @@ -58,6 +58,9 @@
1209  // Get current directory.
1210  extern GString *getCurrentDir();
1211  
1212 +/* create a temporary filename */
1213 +char* mktmpname(char*ptr);
1214 +
1215  // Append a file name to a path string.  <path> may be an empty
1216  // string, denoting the current directory).  Returns <path>.
1217  extern GString *appendToPath(GString *path, char *fileName);
1218 --- xpdf/JBIG2Stream.cc.orig    2010-05-18 11:33:21.000000000 -0700
1219 +++ xpdf/JBIG2Stream.cc 2010-06-03 16:55:03.000000000 -0700
1220 @@ -6,7 +6,24 @@
1221  //
1222  //========================================================================
1223  
1224 -#include <aconf.h>
1225 +//========================================================================
1226 +//
1227 +// Modified under the Poppler project - http://poppler.freedesktop.org
1228 +//
1229 +// All changes made under the Poppler project to this file are licensed
1230 +// under GPL version 2 or later
1231 +//
1232 +// Copyright (C) 2006 Raj Kumar <rkumar@archive.org>
1233 +// Copyright (C) 2006 Paul Walmsley <paul@booyaka.com>
1234 +// Copyright (C) 2006-2009 Albert Astals Cid <aacid@kde.org>
1235 +// Copyright (C) 2009 David Benjamin <davidben@mit.edu>
1236 +//
1237 +// To see a description of the changes please see the Changelog file that
1238 +// came with your tarball or type make ChangeLog if you are building from git
1239 +//
1240 +//========================================================================
1241 +
1242 +#include <config.h>
1243  
1244  #ifdef USE_GCC_PRAGMAS
1245  #pragma implementation
1246 @@ -24,8 +41,8 @@
1247  
1248  //------------------------------------------------------------------------
1249  
1250 -static int contextSize[4] = { 16, 13, 10, 10 };
1251 -static int refContextSize[2] = { 13, 10 };
1252 +static const int contextSize[4] = { 16, 13, 10, 10 };
1253 +static const int refContextSize[2] = { 13, 10 };
1254  
1255  //------------------------------------------------------------------------
1256  // JBIG2HuffmanTable
1257 @@ -42,7 +59,7 @@
1258    Guint prefix;
1259  };
1260  
1261 -JBIG2HuffmanTable huffTableA[] = {
1262 +static JBIG2HuffmanTable huffTableA[] = {
1263    {     0, 1,  4,              0x000 },
1264    {    16, 2,  8,              0x002 },
1265    {   272, 3, 16,              0x006 },
1266 @@ -50,7 +67,7 @@
1267    {     0, 0, jbig2HuffmanEOT, 0     }
1268  };
1269  
1270 -JBIG2HuffmanTable huffTableB[] = {
1271 +static JBIG2HuffmanTable huffTableB[] = {
1272    {     0, 1,  0,              0x000 },
1273    {     1, 2,  0,              0x002 },
1274    {     2, 3,  0,              0x006 },
1275 @@ -61,7 +78,7 @@
1276    {     0, 0, jbig2HuffmanEOT, 0     }
1277  };
1278  
1279 -JBIG2HuffmanTable huffTableC[] = {
1280 +static JBIG2HuffmanTable huffTableC[] = {
1281    {     0, 1,  0,              0x000 },
1282    {     1, 2,  0,              0x002 },
1283    {     2, 3,  0,              0x006 },
1284 @@ -74,7 +91,7 @@
1285    {     0, 0, jbig2HuffmanEOT, 0     }
1286  };
1287  
1288 -JBIG2HuffmanTable huffTableD[] = {
1289 +static JBIG2HuffmanTable huffTableD[] = {
1290    {     1, 1,  0,              0x000 },
1291    {     2, 2,  0,              0x002 },
1292    {     3, 3,  0,              0x006 },
1293 @@ -84,7 +101,7 @@
1294    {     0, 0, jbig2HuffmanEOT, 0     }
1295  };
1296  
1297 -JBIG2HuffmanTable huffTableE[] = {
1298 +static JBIG2HuffmanTable huffTableE[] = {
1299    {     1, 1,  0,              0x000 },
1300    {     2, 2,  0,              0x002 },
1301    {     3, 3,  0,              0x006 },
1302 @@ -96,7 +113,7 @@
1303    {     0, 0, jbig2HuffmanEOT, 0     }
1304  };
1305  
1306 -JBIG2HuffmanTable huffTableF[] = {
1307 +static JBIG2HuffmanTable huffTableF[] = {
1308    {     0, 2,  7,              0x000 },
1309    {   128, 3,  7,              0x002 },
1310    {   256, 3,  8,              0x003 },
1311 @@ -114,7 +131,7 @@
1312    {     0, 0, jbig2HuffmanEOT, 0     }
1313  };
1314  
1315 -JBIG2HuffmanTable huffTableG[] = {
1316 +static JBIG2HuffmanTable huffTableG[] = {
1317    {  -512, 3,  8,              0x000 },
1318    {   256, 3,  8,              0x001 },
1319    {   512, 3,  9,              0x002 },
1320 @@ -133,7 +150,7 @@
1321    {     0, 0, jbig2HuffmanEOT, 0     }
1322  };
1323  
1324 -JBIG2HuffmanTable huffTableH[] = {
1325 +static JBIG2HuffmanTable huffTableH[] = {
1326    {     0, 2,  1,              0x000 },
1327    {     0, 2, jbig2HuffmanOOB, 0x001 },
1328    {     4, 3,  4,              0x004 },
1329 @@ -158,7 +175,7 @@
1330    {     0, 0, jbig2HuffmanEOT, 0     }
1331  };
1332  
1333 -JBIG2HuffmanTable huffTableI[] = {
1334 +static JBIG2HuffmanTable huffTableI[] = {
1335    {     0, 2, jbig2HuffmanOOB, 0x000 },
1336    {    -1, 3,  1,              0x002 },
1337    {     1, 3,  1,              0x003 },
1338 @@ -184,7 +201,7 @@
1339    {     0, 0, jbig2HuffmanEOT, 0     }
1340  };
1341  
1342 -JBIG2HuffmanTable huffTableJ[] = {
1343 +static JBIG2HuffmanTable huffTableJ[] = {
1344    {    -2, 2,  2,              0x000 },
1345    {     6, 2,  6,              0x001 },
1346    {     0, 2, jbig2HuffmanOOB, 0x002 },
1347 @@ -209,7 +226,7 @@
1348    {     0, 0, jbig2HuffmanEOT, 0     }
1349  };
1350  
1351 -JBIG2HuffmanTable huffTableK[] = {
1352 +static JBIG2HuffmanTable huffTableK[] = {
1353    {     1, 1,  0,              0x000 },
1354    {     2, 2,  1,              0x002 },
1355    {     4, 4,  0,              0x00c },
1356 @@ -226,7 +243,7 @@
1357    {     0, 0, jbig2HuffmanEOT, 0     }
1358  };
1359  
1360 -JBIG2HuffmanTable huffTableL[] = {
1361 +static JBIG2HuffmanTable huffTableL[] = {
1362    {     1, 1,  0,              0x000 },
1363    {     2, 2,  0,              0x002 },
1364    {     3, 3,  1,              0x006 },
1365 @@ -243,7 +260,7 @@
1366    {     0, 0, jbig2HuffmanEOT, 0     }
1367  };
1368  
1369 -JBIG2HuffmanTable huffTableM[] = {
1370 +static JBIG2HuffmanTable huffTableM[] = {
1371    {     1, 1,  0,              0x000 },
1372    {     2, 3,  0,              0x004 },
1373    {     7, 3,  3,              0x005 },
1374 @@ -260,7 +277,7 @@
1375    {     0, 0, jbig2HuffmanEOT, 0     }
1376  };
1377  
1378 -JBIG2HuffmanTable huffTableN[] = {
1379 +static JBIG2HuffmanTable huffTableN[] = {
1380    {     0, 1,  0,              0x000 },
1381    {    -2, 3,  0,              0x004 },
1382    {    -1, 3,  0,              0x005 },
1383 @@ -269,7 +286,7 @@
1384    {     0, 0, jbig2HuffmanEOT, 0     }
1385  };
1386  
1387 -JBIG2HuffmanTable huffTableO[] = {
1388 +static JBIG2HuffmanTable huffTableO[] = {
1389    {     0, 1,  0,              0x000 },
1390    {    -1, 3,  0,              0x004 },
1391    {     1, 3,  0,              0x005 },
1392 @@ -473,7 +490,7 @@
1393  }
1394  
1395  int JBIG2MMRDecoder::get2DCode() {
1396 -  CCITTCode *p;
1397 +  const CCITTCode *p;
1398  
1399    if (bufLen == 0) {
1400      buf = str->getChar() & 0xff;
1401 @@ -500,7 +517,7 @@
1402  }
1403  
1404  int JBIG2MMRDecoder::getWhiteCode() {
1405 -  CCITTCode *p;
1406 +  const CCITTCode *p;
1407    Guint code;
1408  
1409    if (bufLen == 0) {
1410 @@ -543,7 +560,7 @@
1411  }
1412  
1413  int JBIG2MMRDecoder::getBlackCode() {
1414 -  CCITTCode *p;
1415 +  const CCITTCode *p;
1416    Guint code;
1417  
1418    if (bufLen == 0) {
1419 @@ -670,6 +687,7 @@
1420    void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
1421    Guchar *getDataPtr() { return data; }
1422    int getDataSize() { return h * line; }
1423 +  GBool isOk() { return data != NULL; }
1424  
1425  private:
1426  
1427 @@ -685,10 +703,11 @@
1428    w = wA;
1429    h = hA;
1430    line = (wA + 7) >> 3;
1431 +
1432    if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
1433 -    // force a call to gmalloc(-1), which will throw an exception
1434 -    h = -1;
1435 -    line = 2;
1436 +    error(-1, "invalid width/height");
1437 +    data = NULL;
1438 +    return;
1439    }
1440    // need to allocate one extra guard byte for use in combine()
1441    data = (Guchar *)gmalloc(h * line + 1);
1442 @@ -701,10 +720,11 @@
1443    w = bitmap->w;
1444    h = bitmap->h;
1445    line = bitmap->line;
1446 +
1447    if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
1448 -    // force a call to gmalloc(-1), which will throw an exception
1449 -    h = -1;
1450 -    line = 2;
1451 +    error(-1, "invalid width/height");
1452 +    data = NULL;
1453 +    return;
1454    }
1455    // need to allocate one extra guard byte for use in combine()
1456    data = (Guchar *)gmalloc(h * line + 1);
1457 @@ -735,6 +755,9 @@
1458  
1459  void JBIG2Bitmap::expand(int newH, Guint pixel) {
1460    if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
1461 +    error(-1, "invalid width/height");
1462 +    gfree(data);
1463 +    data = NULL;
1464      return;
1465    }
1466    // need to allocate one extra guard byte for use in combine()
1467 @@ -1002,6 +1025,7 @@
1468    Guint getSize() { return size; }
1469    void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1470    JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1471 +  GBool isOk() { return bitmaps != NULL; }
1472    void setGenericRegionStats(JArithmeticDecoderStats *stats)
1473      { genericRegionStats = stats; }
1474    void setRefinementRegionStats(JArithmeticDecoderStats *stats)
1475 @@ -1022,13 +1046,9 @@
1476  JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
1477    JBIG2Segment(segNumA)
1478  {
1479 -  Guint i;
1480 -
1481    size = sizeA;
1482    bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
1483 -  for (i = 0; i < size; ++i) {
1484 -    bitmaps[i] = NULL;
1485 -  }
1486 +  if (!bitmaps) size = 0;
1487    genericRegionStats = NULL;
1488    refinementRegionStats = NULL;
1489  }
1490 @@ -1037,9 +1057,7 @@
1491    Guint i;
1492  
1493    for (i = 0; i < size; ++i) {
1494 -    if (bitmaps[i]) {
1495 -      delete bitmaps[i];
1496 -    }
1497 +    delete bitmaps[i];
1498    }
1499    gfree(bitmaps);
1500    if (genericRegionStats) {
1501 @@ -1247,6 +1265,7 @@
1502    Guint segNum, segFlags, segType, page, segLength;
1503    Guint refFlags, nRefSegs;
1504    Guint *refSegs;
1505 +  int segDataPos;
1506    int c1, c2, c3;
1507    Guint i;
1508  
1509 @@ -1314,6 +1333,9 @@
1510        goto eofError2;
1511      }
1512  
1513 +    // keep track of the start of the segment data 
1514 +    segDataPos = getPos();
1515 +
1516      // check for missing page information segment
1517      if (!pageBitmap && ((segType >= 4 && segType <= 7) ||
1518                         (segType >= 20 && segType <= 43))) {
1519 @@ -1398,6 +1420,45 @@
1520        break;
1521      }
1522  
1523 +    // Make sure the segment handler read all of the bytes in the 
1524 +    // segment data, unless this segment is marked as having an
1525 +    // unknown length (section 7.2.7 of the JBIG2 Final Committee Draft)
1526 +
1527 +    if (segLength != 0xffffffff) {
1528 +
1529 +      int segExtraBytes = segDataPos + segLength - getPos();
1530 +      if (segExtraBytes > 0) {
1531 +
1532 +       // If we didn't read all of the bytes in the segment data,
1533 +       // indicate an error, and throw away the rest of the data.
1534 +       
1535 +       // v.3.1.01.13 of the LuraTech PDF Compressor Server will
1536 +       // sometimes generate an extraneous NULL byte at the end of
1537 +       // arithmetic-coded symbol dictionary segments when numNewSyms
1538 +       // == 0.  Segments like this often occur for blank pages.
1539 +       
1540 +       error(getPos(), "%d extraneous byte%s after segment",
1541 +             segExtraBytes, (segExtraBytes > 1) ? "s" : "");
1542 +       
1543 +       // Burn through the remaining bytes -- inefficient, but
1544 +       // hopefully we're not doing this much
1545 +       
1546 +       int trash;
1547 +       for (int i = segExtraBytes; i > 0; i--) {
1548 +         readByte(&trash);
1549 +       }
1550 +       
1551 +      } else if (segExtraBytes < 0) {
1552 +       
1553 +       // If we read more bytes than we should have, according to the 
1554 +       // segment length field, note an error.
1555 +       
1556 +       error(getPos(), "Previous segment handler read too many bytes");
1557 +       
1558 +      }
1559 +
1560 +    }
1561 +    
1562      gfree(refSegs);
1563    }
1564  
1565 @@ -1493,6 +1554,9 @@
1566    codeTables = new GList();
1567    numInputSyms = 0;
1568    for (i = 0; i < nRefSegs; ++i) {
1569 +    // This is need by bug 12014, returning gFalse makes it not crash
1570 +    // but we end up with a empty page while acroread is able to render
1571 +    // part of it
1572      if ((seg = findSegment(refSegs[i]))) {
1573        if (seg->getType() == jbig2SegSymbolDict) {
1574         j = ((JBIG2SymbolDict *)seg)->getSize();
1575 @@ -1503,8 +1567,11 @@
1576         }
1577         numInputSyms += j;
1578        } else if (seg->getType() == jbig2SegCodeTable) {
1579 -       codeTables->append(seg);
1580 +        codeTables->append(seg);
1581        }
1582 +    } else {
1583 +      delete codeTables;
1584 +      return gFalse;
1585      }
1586    }
1587    if (numInputSyms > UINT_MAX - numNewSyms) {
1588 @@ -1530,12 +1600,11 @@
1589    k = 0;
1590    inputSymbolDict = NULL;
1591    for (i = 0; i < nRefSegs; ++i) {
1592 -    if ((seg = findSegment(refSegs[i]))) {
1593 -      if (seg->getType() == jbig2SegSymbolDict) {
1594 -       inputSymbolDict = (JBIG2SymbolDict *)seg;
1595 -       for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1596 -         bitmaps[k++] = inputSymbolDict->getBitmap(j);
1597 -       }
1598 +    seg = findSegment(refSegs[i]);
1599 +    if (seg != NULL && seg->getType() == jbig2SegSymbolDict) {
1600 +      inputSymbolDict = (JBIG2SymbolDict *)seg;
1601 +      for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1602 +       bitmaps[k++] = inputSymbolDict->getBitmap(j);
1603        }
1604      }
1605    }
1606 @@ -1753,6 +1822,10 @@
1607  
1608    // create the symbol dict object
1609    symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1610 +  if (!symbolDict->isOk()) {
1611 +    delete symbolDict;
1612 +    goto syntaxError;
1613 +  }
1614  
1615    // exported symbol list
1616    i = j = 0;
1617 @@ -1766,6 +1839,7 @@
1618      if (i + run > numInputSyms + numNewSyms ||
1619         (ex && j + run > numExSyms)) {
1620        error(getPos(), "Too many exported symbols in JBIG2 symbol dictionary");
1621 +      for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
1622        delete symbolDict;
1623        goto syntaxError;
1624      }
1625 @@ -1780,6 +1854,7 @@
1626    }
1627    if (j != numExSyms) {
1628      error(getPos(), "Too few symbols in JBIG2 symbol dictionary");
1629 +    for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
1630      delete symbolDict;
1631      goto syntaxError;
1632    }
1633 @@ -2095,18 +2170,20 @@
1634  
1635    gfree(syms);
1636  
1637 -  // combine the region bitmap into the page bitmap
1638 -  if (imm) {
1639 -    if (pageH == 0xffffffff && y + h > curPageH) {
1640 -      pageBitmap->expand(y + h, pageDefPixel);
1641 -    }
1642 -    pageBitmap->combine(bitmap, x, y, extCombOp);
1643 -    delete bitmap;
1644 +  if (bitmap) {
1645 +    // combine the region bitmap into the page bitmap
1646 +    if (imm) {
1647 +      if (pageH == 0xffffffff && y + h > curPageH) {
1648 +        pageBitmap->expand(y + h, pageDefPixel);
1649 +      }
1650 +      pageBitmap->combine(bitmap, x, y, extCombOp);
1651 +      delete bitmap;
1652  
1653 -  // store the region bitmap
1654 -  } else {
1655 -    bitmap->setSegNum(segNum);
1656 -    segments->append(bitmap);
1657 +    // store the region bitmap
1658 +    } else {
1659 +      bitmap->setSegNum(segNum);
1660 +      segments->append(bitmap);
1661 +    }
1662    }
1663  
1664    // clean up the Huffman decoder
1665 @@ -2159,6 +2236,10 @@
1666  
1667    // allocate the bitmap
1668    bitmap = new JBIG2Bitmap(0, w, h);
1669 +  if (!bitmap->isOk()) {
1670 +    delete bitmap;
1671 +    return NULL;
1672 +  }
1673    if (defPixel) {
1674      bitmap->clearToOne();
1675    } else {
1676 @@ -2235,73 +2316,84 @@
1677           ri = 0;
1678         }
1679         if (ri) {
1680 +         GBool decodeSuccess;
1681           if (huff) {
1682 -           huffDecoder->decodeInt(&rdw, huffRDWTable);
1683 -           huffDecoder->decodeInt(&rdh, huffRDHTable);
1684 -           huffDecoder->decodeInt(&rdx, huffRDXTable);
1685 -           huffDecoder->decodeInt(&rdy, huffRDYTable);
1686 -           huffDecoder->decodeInt(&bmSize, huffRSizeTable);
1687 +           decodeSuccess = huffDecoder->decodeInt(&rdw, huffRDWTable);
1688 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdh, huffRDHTable);
1689 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdx, huffRDXTable);
1690 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdy, huffRDYTable);
1691 +           decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&bmSize, huffRSizeTable);
1692             huffDecoder->reset();
1693             arithDecoder->start();
1694           } else {
1695 -           arithDecoder->decodeInt(&rdw, iardwStats);
1696 -           arithDecoder->decodeInt(&rdh, iardhStats);
1697 -           arithDecoder->decodeInt(&rdx, iardxStats);
1698 -           arithDecoder->decodeInt(&rdy, iardyStats);
1699 +           decodeSuccess = arithDecoder->decodeInt(&rdw, iardwStats);
1700 +           decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdh, iardhStats);
1701 +           decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdx, iardxStats);
1702 +           decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdy, iardyStats);
1703 +         }
1704 +         
1705 +         if (decodeSuccess && syms[symID])
1706 +         {
1707 +           refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
1708 +           refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
1709 +
1710 +           symbolBitmap =
1711 +             readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
1712 +                                         rdh + syms[symID]->getHeight(),
1713 +                                         templ, gFalse, syms[symID],
1714 +                                         refDX, refDY, atx, aty);
1715           }
1716 -         refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
1717 -         refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
1718 -
1719 -         symbolBitmap =
1720 -           readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
1721 -                                       rdh + syms[symID]->getHeight(),
1722 -                                       templ, gFalse, syms[symID],
1723 -                                       refDX, refDY, atx, aty);
1724           //~ do we need to use the bmSize value here (in Huffman mode)?
1725         } else {
1726           symbolBitmap = syms[symID];
1727         }
1728  
1729 -       // combine the symbol bitmap into the region bitmap
1730 -       //~ something is wrong here - refCorner shouldn't degenerate into
1731 -       //~   two cases
1732 -       bw = symbolBitmap->getWidth() - 1;
1733 -       bh = symbolBitmap->getHeight() - 1;
1734 -       if (transposed) {
1735 -         switch (refCorner) {
1736 -         case 0: // bottom left
1737 -           bitmap->combine(symbolBitmap, tt, s, combOp);
1738 -           break;
1739 -         case 1: // top left
1740 -           bitmap->combine(symbolBitmap, tt, s, combOp);
1741 -           break;
1742 -         case 2: // bottom right
1743 -           bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1744 -           break;
1745 -         case 3: // top right
1746 -           bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1747 -           break;
1748 +       if (symbolBitmap) {
1749 +         // combine the symbol bitmap into the region bitmap
1750 +         //~ something is wrong here - refCorner shouldn't degenerate into
1751 +         //~   two cases
1752 +         bw = symbolBitmap->getWidth() - 1;
1753 +         bh = symbolBitmap->getHeight() - 1;
1754 +         if (transposed) {
1755 +           switch (refCorner) {
1756 +           case 0: // bottom left
1757 +             bitmap->combine(symbolBitmap, tt, s, combOp);
1758 +             break;
1759 +           case 1: // top left
1760 +             bitmap->combine(symbolBitmap, tt, s, combOp);
1761 +             break;
1762 +           case 2: // bottom right
1763 +             bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1764 +             break;
1765 +           case 3: // top right
1766 +             bitmap->combine(symbolBitmap, tt - bw, s, combOp);
1767 +             break;
1768 +           }
1769 +           s += bh;
1770 +         } else {
1771 +           switch (refCorner) {
1772 +           case 0: // bottom left
1773 +             bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1774 +             break;
1775 +           case 1: // top left
1776 +             bitmap->combine(symbolBitmap, s, tt, combOp);
1777 +             break;
1778 +           case 2: // bottom right
1779 +             bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1780 +             break;
1781 +           case 3: // top right
1782 +             bitmap->combine(symbolBitmap, s, tt, combOp);
1783 +             break;
1784 +           }
1785 +           s += bw;
1786           }
1787 -         s += bh;
1788 -       } else {
1789 -         switch (refCorner) {
1790 -         case 0: // bottom left
1791 -           bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1792 -           break;
1793 -         case 1: // top left
1794 -           bitmap->combine(symbolBitmap, s, tt, combOp);
1795 -           break;
1796 -         case 2: // bottom right
1797 -           bitmap->combine(symbolBitmap, s, tt - bh, combOp);
1798 -           break;
1799 -         case 3: // top right
1800 -           bitmap->combine(symbolBitmap, s, tt, combOp);
1801 -           break;
1802 +         if (ri) {
1803 +           delete symbolBitmap;
1804           }
1805 -         s += bw;
1806 -       }
1807 -       if (ri) {
1808 -         delete symbolBitmap;
1809 +       } else {
1810 +         // NULL symbolBitmap only happens on error
1811 +         delete bitmap;
1812 +         return NULL;
1813         }
1814        }
1815  
1816 @@ -2431,11 +2523,12 @@
1817      error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
1818      return;
1819    }
1820 -  if (!(seg = findSegment(refSegs[0])) ||
1821 -      seg->getType() != jbig2SegPatternDict) {
1822 +  seg = findSegment(refSegs[0]);
1823 +  if (seg == NULL || seg->getType() != jbig2SegPatternDict) {
1824      error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
1825      return;
1826    }
1827 +
1828    patternDict = (JBIG2PatternDict *)seg;
1829    bpp = 0;
1830    i = 1;
1831 @@ -2591,6 +2684,8 @@
1832    // read the bitmap
1833    bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
1834                              NULL, atx, aty, mmr ? length - 18 : 0);
1835 +  if (!bitmap)
1836 +    return;
1837  
1838    // combine the region bitmap into the page bitmap
1839    if (imm) {
1840 @@ -2616,7 +2711,7 @@
1841                                       int *codingLine, int *a0i, int w) {
1842    if (a1 > codingLine[*a0i]) {
1843      if (a1 > w) {
1844 -      error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
1845 +      error(getPos(), "JBIG2 MMR row is wrong length (%d)", a1);
1846        a1 = w;
1847      }
1848      if ((*a0i & 1) ^ blackPixels) {
1849 @@ -2630,7 +2725,7 @@
1850                                          int *codingLine, int *a0i, int w) {
1851    if (a1 > codingLine[*a0i]) {
1852      if (a1 > w) {
1853 -      error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
1854 +      error(getPos(), "JBIG2 MMR row is wrong length (%d)", a1);
1855        a1 = w;
1856      }
1857      if ((*a0i & 1) ^ blackPixels) {
1858 @@ -2657,13 +2752,17 @@
1859    JBIG2Bitmap *bitmap;
1860    GBool ltp;
1861    Guint ltpCX, cx, cx0, cx1, cx2;
1862 -  JBIG2BitmapPtr cxPtr0, cxPtr1;
1863 -  JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3;
1864 +  JBIG2BitmapPtr cxPtr0 = {0}, cxPtr1 = {0};
1865 +  JBIG2BitmapPtr atPtr0 = {0}, atPtr1 = {0}, atPtr2 = {0}, atPtr3 = {0};
1866    int *refLine, *codingLine;
1867    int code1, code2, code3;
1868    int x, y, a0i, b1i, blackPixels, pix, i;
1869  
1870    bitmap = new JBIG2Bitmap(0, w, h);
1871 +  if (!bitmap->isOk()) {
1872 +    delete bitmap;
1873 +    return NULL;
1874 +  }
1875    bitmap->clearToZero();
1876  
1877    //----- MMR decode
1878 @@ -2682,7 +2781,7 @@
1879      // ---> max refLine size = w + 2
1880      codingLine = (int *)gmallocn(w + 1, sizeof(int));
1881      refLine = (int *)gmallocn(w + 2, sizeof(int));
1882 -    codingLine[0] = w;
1883 +    for (i = 0; i < w + 1; ++i) codingLine[i] = w;
1884  
1885      for (y = 0; y < h; ++y) {
1886  
1887 @@ -3093,8 +3192,8 @@
1888      return;
1889    }
1890    if (nRefSegs == 1) {
1891 -    if (!(seg = findSegment(refSegs[0])) ||
1892 -       seg->getType() != jbig2SegBitmap) {
1893 +    seg = findSegment(refSegs[0]);
1894 +    if (seg == NULL || seg->getType() != jbig2SegBitmap) {
1895        error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
1896        return;
1897      }
1898 @@ -3143,11 +3242,24 @@
1899    JBIG2Bitmap *bitmap;
1900    GBool ltp;
1901    Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
1902 -  JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
1903 -  JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
1904 +  JBIG2BitmapPtr cxPtr0 = {0};
1905 +  JBIG2BitmapPtr cxPtr1 = {0};
1906 +  JBIG2BitmapPtr cxPtr2 = {0};
1907 +  JBIG2BitmapPtr cxPtr3 = {0};
1908 +  JBIG2BitmapPtr cxPtr4 = {0};
1909 +  JBIG2BitmapPtr cxPtr5 = {0};
1910 +  JBIG2BitmapPtr cxPtr6 = {0};
1911 +  JBIG2BitmapPtr tpgrCXPtr0 = {0};
1912 +  JBIG2BitmapPtr tpgrCXPtr1 = {0};
1913 +  JBIG2BitmapPtr tpgrCXPtr2 = {0};
1914    int x, y, pix;
1915  
1916    bitmap = new JBIG2Bitmap(0, w, h);
1917 +  if (!bitmap->isOk())
1918 +  {
1919 +    delete bitmap;
1920 +    return NULL;
1921 +  }
1922    bitmap->clearToZero();
1923  
1924    // set up the typical row context
1925 @@ -3332,6 +3444,12 @@
1926    }
1927    pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
1928  
1929 +  if (!pageBitmap->isOk()) {
1930 +    delete pageBitmap;
1931 +    pageBitmap = NULL;
1932 +    return;
1933 +  }
1934 +  
1935    // default pixel value
1936    if (pageDefPixel) {
1937      pageBitmap->clearToOne();