[poppler] Branch 'xpdf303merge' - fofi/FoFiBase.cc fofi/FoFiTrueType.cc fofi/FoFiType1.cc goo/JpegWriter.cc goo/PNGWriter.cc poppler/Annot.cc poppler/ArthurOutputDev.cc poppler/CachedFile.cc poppler/CairoFontEngine.cc poppler/Catalog.cc poppler/CharCodeToUnicode.cc poppler/CMap.cc poppler/CurlCachedFile.cc poppler/DCTStream.cc poppler/Decrypt.cc poppler/Error.cc poppler/Error.h poppler/FileSpec.cc poppler/Form.cc poppler/Function.cc poppler/Gfx.cc poppler/GfxFont.cc poppler/GfxState.cc poppler/GfxState.h poppler/GlobalParams.cc poppler/GlobalParamsWin.cc poppler/Hints.cc poppler/JBIG2Stream.cc poppler/JPEG2000Stream.cc poppler/JPXStream.cc poppler/Lexer.cc poppler/Linearization.cc poppler/Link.cc poppler/Movie.cc poppler/Object.h poppler/OptionalContent.cc poppler/Page.cc poppler/Parser.cc poppler/PDFDoc.cc poppler/PDFDocFactory.cc poppler/PSOutputDev.cc poppler/Rendition.cc poppler/SecurityHandler.cc poppler/SplashOutputDev.cc poppler/Stream.cc poppler/TextOutputDev.cc popple r/UnicodeMap.cc poppler/XRef.cc splash/SplashBitmap.cc splash/Splash.cc test/perf-test.cc utils/HtmlOutputDev.cc utils/ImageOutputDev.cc utils/pdfextract.cc utils/pdfimages.cc utils/pdfinfo.cc utils/pdfmerge.cc utils/pdftocairo.cc utils/pdftohtml.cc utils/pdftops.cc utils/pdftotext.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Wed Aug 31 10:03:39 PDT 2011


 fofi/FoFiBase.cc             |    8 +-
 fofi/FoFiTrueType.cc         |    2 
 fofi/FoFiType1.cc            |    4 -
 goo/JpegWriter.cc            |    2 
 goo/PNGWriter.cc             |   16 ++--
 poppler/Annot.cc             |   40 +++++-----
 poppler/ArthurOutputDev.cc   |   16 ++--
 poppler/CMap.cc              |   26 +++---
 poppler/CachedFile.cc        |    2 
 poppler/CairoFontEngine.cc   |   10 +-
 poppler/Catalog.cc           |   50 ++++++-------
 poppler/CharCodeToUnicode.cc |   54 +++++++-------
 poppler/CurlCachedFile.cc    |    2 
 poppler/DCTStream.cc         |    2 
 poppler/Decrypt.cc           |    2 
 poppler/Error.cc             |   55 +++++++++-----
 poppler/Error.h              |   23 +++++-
 poppler/FileSpec.cc          |    8 +-
 poppler/Form.cc              |   44 +++++------
 poppler/Function.cc          |  107 ++++++++++++++--------------
 poppler/Gfx.cc               |  161 +++++++++++++++++++++---------------------
 poppler/GfxFont.cc           |  102 +++++++++++++-------------
 poppler/GfxState.cc          |  128 ++++++++++++++++-----------------
 poppler/GfxState.h           |    8 +-
 poppler/GlobalParams.cc      |   38 ++++-----
 poppler/GlobalParamsWin.cc   |    4 -
 poppler/Hints.cc             |   22 ++---
 poppler/JBIG2Stream.cc       |   88 +++++++++++------------
 poppler/JPEG2000Stream.cc    |   10 +-
 poppler/JPXStream.cc         |  164 ++++++++++++++++++++++---------------------
 poppler/Lexer.cc             |   24 +++---
 poppler/Linearization.cc     |   20 ++---
 poppler/Link.cc              |   77 ++++++++++----------
 poppler/Movie.cc             |    2 
 poppler/Object.h             |    8 +-
 poppler/OptionalContent.cc   |   14 +--
 poppler/PDFDoc.cc            |   43 +++++------
 poppler/PDFDocFactory.cc     |    2 
 poppler/PSOutputDev.cc       |   45 ++++++-----
 poppler/Page.cc              |   12 +--
 poppler/Parser.cc            |   10 +-
 poppler/Rendition.cc         |    6 -
 poppler/SecurityHandler.cc   |   12 +--
 poppler/SplashOutputDev.cc   |   28 +++----
 poppler/Stream.cc            |  116 +++++++++++++++++-------------
 poppler/TextOutputDev.cc     |    2 
 poppler/UnicodeMap.cc        |   15 ++-
 poppler/XRef.cc              |   32 ++++----
 splash/Splash.cc             |    2 
 splash/SplashBitmap.cc       |    6 -
 test/perf-test.cc            |    4 -
 utils/HtmlOutputDev.cc       |   18 ++--
 utils/ImageOutputDev.cc      |   10 +-
 utils/pdfextract.cc          |    4 -
 utils/pdfimages.cc           |    2 
 utils/pdfinfo.cc             |    6 -
 utils/pdfmerge.cc            |    6 -
 utils/pdftocairo.cc          |    6 -
 utils/pdftohtml.cc           |    6 -
 utils/pdftops.cc             |    6 -
 utils/pdftotext.cc           |   12 +--
 61 files changed, 912 insertions(+), 842 deletions(-)

New commits:
commit 00549400f155d8e36b4ac718603fc945858fe50d
Author: Albert Astals Cid <aacid at kde.org>
Date:   Wed Aug 31 19:04:14 2011 +0200

    xpdf303: error() changes, new param and formatting

diff --git a/fofi/FoFiBase.cc b/fofi/FoFiBase.cc
index 06d12e8..86bafd8 100644
--- a/fofi/FoFiBase.cc
+++ b/fofi/FoFiBase.cc
@@ -55,22 +55,22 @@ char *FoFiBase::readFile(char *fileName, int *fileLen) {
   int n;
 
   if (!(f = fopen(fileName, "rb"))) {
-    error(-1, "Cannot open '%s'", fileName);
+    error(errIO, -1, "Cannot open '{0:s}'", fileName);
     return NULL;
   }
   if (fseek(f, 0, SEEK_END) != 0) {
-    error(-1, "Cannot seek to end of '%s'", fileName);
+    error(errIO, -1, "Cannot seek to end of '{0:s}'", fileName);
     fclose(f);
     return NULL;
   }
   n = (int)ftell(f);
   if (n < 0) {
-    error(-1, "Cannot determine length of '%s'", fileName);
+    error(errIO, -1, "Cannot determine length of '{0:s}'", fileName);
     fclose(f);
     return NULL;
   }
   if (fseek(f, 0, SEEK_SET) != 0) {
-    error(-1, "Cannot seek to start of '%s'", fileName);
+    error(errIO, -1, "Cannot seek to start of '{0:s}'", fileName);
     fclose(f);
     return NULL;
   }
diff --git a/fofi/FoFiTrueType.cc b/fofi/FoFiTrueType.cc
index a2c1195..7db63e1 100644
--- a/fofi/FoFiTrueType.cc
+++ b/fofi/FoFiTrueType.cc
@@ -1976,7 +1976,7 @@ void FoFiTrueType::parse() {
 	tables[i].offset + tables[i].len > len) {
       i--;
       wrongTables++;
-      error(-1, "Found a bad table definition on true type definition, trying to continue...");
+      error(errSyntaxWarning, -1, "Found a bad table definition on true type definition, trying to continue...");
     }
     pos += 16;
   }
diff --git a/fofi/FoFiType1.cc b/fofi/FoFiType1.cc
index b6c3408..00f2cf9 100644
--- a/fofi/FoFiType1.cc
+++ b/fofi/FoFiType1.cc
@@ -224,7 +224,7 @@ void FoFiType1::parse() {
 	   j < 300 && line && (line1 = getNextLine(line));
 	   ++j, line = line1) {
 	if ((n = line1 - line) > 255) {
-	  error(-1, "FoFiType1::parse a line has more than 255 characters, we don't support this");
+	  error(errSyntaxWarning, -1, "FoFiType1::parse a line has more than 255 characters, we don't support this");
 	  n = 255;
 	}
 	strncpy(buf, line, n);
@@ -267,7 +267,7 @@ void FoFiType1::parse() {
 		    line1 = &line[p - buf];
 		  }
 		} else {
-		  error(-1, "FoFiType1::parse no put after dup");
+		  error(errSyntaxWarning, -1, "FoFiType1::parse no put after dup");
 		}
 	      }
 	    }
diff --git a/goo/JpegWriter.cc b/goo/JpegWriter.cc
index 7ed5d52..201414b 100644
--- a/goo/JpegWriter.cc
+++ b/goo/JpegWriter.cc
@@ -25,7 +25,7 @@ void outputMessage(j_common_ptr cinfo)
 	(*cinfo->err->format_message) (cinfo, buffer);
 
 	// Send it to poppler's error handler
-	error(-1, "%s", buffer);
+	error(errInternal, -1, "{0:s}", buffer);
 }
 
 JpegWriter::JpegWriter(int q, bool p, J_COLOR_SPACE cm)
diff --git a/goo/PNGWriter.cc b/goo/PNGWriter.cc
index d47efa6..d5b5df5 100644
--- a/goo/PNGWriter.cc
+++ b/goo/PNGWriter.cc
@@ -59,25 +59,25 @@ bool PNGWriter::init(FILE *f, int width, int height, int hDPI, int vDPI)
 	/* initialize stuff */
 	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 	if (!png_ptr) {
-		error(-1, "png_create_write_struct failed");
+		error(errInternal, -1, "png_create_write_struct failed");
 		return false;
 	}
 
 	info_ptr = png_create_info_struct(png_ptr);
 	if (!info_ptr) {
-		error(-1, "png_create_info_struct failed");
+		error(errInternal, -1, "png_create_info_struct failed");
 		return false;
 	}
 
 	if (setjmp(png_jmpbuf(png_ptr))) {
-		error(-1, "png_jmpbuf failed");
+		error(errInternal, -1, "png_jmpbuf failed");
 		return false;
 	}
 
 	/* write header */
 	png_init_io(png_ptr, f);
 	if (setjmp(png_jmpbuf(png_ptr))) {
-		error(-1, "Error during writing header");
+		error(errInternal, -1, "Error during writing header");
 		return false;
 	}
 	
@@ -118,7 +118,7 @@ bool PNGWriter::init(FILE *f, int width, int height, int hDPI, int vDPI)
 
 	png_write_info(png_ptr, info_ptr);
 	if (setjmp(png_jmpbuf(png_ptr))) {
-		error(-1, "error during writing png info bytes");
+		error(errInternal, -1, "error during writing png info bytes");
 		return false;
 	}
 
@@ -134,7 +134,7 @@ bool PNGWriter::writePointers(unsigned char **rowPointers, int rowCount)
 	png_write_image(png_ptr, rowPointers);
 	/* write bytes */
 	if (setjmp(png_jmpbuf(png_ptr))) {
-		error(-1, "Error during writing bytes");
+		error(errInternal, -1, "Error during writing bytes");
 		return false;
 	}
 	
@@ -146,7 +146,7 @@ bool PNGWriter::writeRow(unsigned char **row)
 	// Write the row to the file
 	png_write_rows(png_ptr, row, 1);
 	if (setjmp(png_jmpbuf(png_ptr))) {
-		error(-1, "error during png row write");
+		error(errInternal, -1, "error during png row write");
 		return false;
 	}
 	
@@ -158,7 +158,7 @@ bool PNGWriter::close()
 	/* end write */
 	png_write_end(png_ptr, info_ptr);
 	if (setjmp(png_jmpbuf(png_ptr))) {
-		error(-1, "Error during end of write");
+		error(errInternal, -1, "Error during end of write");
 		return false;
 	}
 	
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 7f92c18..3e0fb3e 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -251,7 +251,7 @@ void AnnotPath::parsePathArray(Array *array) {
   GBool correct = gTrue;
 
   if (array->getLength() % 2) {
-    error(-1, "Bad Annot Path");
+    error(errSyntaxError, -1, "Bad Annot Path");
     return;
   }
 
@@ -341,7 +341,7 @@ AnnotQuadrilaterals::AnnotQuadrilaterals(Array *array, PDFRectangle *rect) {
         } else {
             correct = gFalse;
 	    obj.free();
-	    error (-1, "Invalid QuadPoint in annot");
+	    error (errSyntaxError, -1, "Invalid QuadPoint in annot");
 	    break;
         }
         obj.free();
@@ -895,7 +895,7 @@ void Annot::initialize(XRef *xrefA, Dict *dict, Catalog *catalog) {
   } else {
     rect->x1 = rect->y1 = 0;
     rect->x2 = rect->y2 = 1;
-    error(-1, "Bad bounding box for annotation");
+    error(errSyntaxError, -1, "Bad bounding box for annotation");
     ok = gFalse;
   }
   obj1.free();
@@ -1005,7 +1005,7 @@ void Annot::initialize(XRef *xrefA, Dict *dict, Catalog *catalog) {
   optContentConfig = catalog ? catalog->getOptContentConfig() : NULL;
   dict->lookupNF("OC", &oc);
   if (!oc.isRef() && !oc.isNull()) {
-    error (-1, "Annotation OC value not null or dict: %i", oc.getType());
+    error (errSyntaxError, -1, "Annotation OC value not null or dict: {0:d}", oc.getType());
   }
 }
 
@@ -2133,7 +2133,7 @@ void AnnotFreeText::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
     appearanceString = obj1.getString()->copy();
   } else {
     appearanceString = new GooString();
-    error(-1, "Bad appearance for annotation");
+    error(errSyntaxError, -1, "Bad appearance for annotation");
     ok = gFalse;
   }
   obj1.free();
@@ -2545,7 +2545,7 @@ void AnnotTextMarkup::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
   if(dict->lookup("QuadPoints", &obj1)->isArray()) {
     quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
   } else {
-    error(-1, "Bad Annot Text Markup QuadPoints");
+    error(errSyntaxError, -1, "Bad Annot Text Markup QuadPoints");
     quadrilaterals = NULL;
     ok = gFalse;
   }
@@ -2815,7 +2815,7 @@ void AnnotWidget::layoutText(GooString *text, GooString *outBuf, int *i,
   int last_i1, last_i2, last_o1, last_o2;
 
   if (unicode && text->getLength() % 2 != 0) {
-    error(-1, "AnnotWidget::layoutText, bad unicode string");
+    error(errSyntaxError, -1, "AnnotWidget::layoutText, bad unicode string");
     return;
   }
 
@@ -3083,16 +3083,16 @@ void AnnotWidget::drawText(GooString *text, GooString *da, GfxResources *resourc
           freeFont = gTrue;
           addDingbatsResource = gTrue;
         } else {
-          error(-1, "Unknown font in field's DA string");
+          error(errSyntaxError, -1, "Unknown font in field's DA string");
         }
       }
     } else {
-      error(-1, "Invalid font name in 'Tf' operator in field's DA string");
+      error(errSyntaxError, -1, "Invalid font name in 'Tf' operator in field's DA string");
     }
     tok = (GooString *)daToks->get(tfPos + 1);
     fontSize = gatof(tok->getCString());
   } else {
-    error(-1, "Missing 'Tf' operator in field's DA string");
+    error(errSyntaxError, -1, "Missing 'Tf' operator in field's DA string");
   }
   if (!font) {
     if (daToks) {
@@ -3442,15 +3442,15 @@ void AnnotWidget::drawListBox(FormFieldChoice *fieldChoice,
     tok = (GooString *)daToks->get(tfPos);
     if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
       if (!resources || !(font = resources->lookupFont(tok->getCString() + 1))) {
-        error(-1, "Unknown font in field's DA string");
+        error(errSyntaxError, -1, "Unknown font in field's DA string");
       }
     } else {
-      error(-1, "Invalid font name in 'Tf' operator in field's DA string");
+      error(errSyntaxError, -1, "Invalid font name in 'Tf' operator in field's DA string");
     }
     tok = (GooString *)daToks->get(tfPos + 1);
     fontSize = gatof(tok->getCString());
   } else {
-    error(-1, "Missing 'Tf' operator in field's DA string");
+    error(errSyntaxError, -1, "Missing 'Tf' operator in field's DA string");
   }
   if (!font) {
     if (daToks) {
@@ -3794,7 +3794,7 @@ void AnnotWidget::generateFieldAppearance() {
     break;
   case formUndef:
   default:
-    error(-1, "Unknown field type");
+    error(errSyntaxError, -1, "Unknown field type");
   }
 
   // build the appearance stream dictionary
@@ -3935,7 +3935,7 @@ void AnnotMovie::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) {
     }
     obj2.free();
   } else {
-    error(-1, "Bad Annot Movie");
+    error(errSyntaxError, -1, "Bad Annot Movie");
     movie = NULL;
     ok = gFalse;
   }
@@ -4076,7 +4076,7 @@ void AnnotScreen::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) {
   if (dict->lookup("A", &obj1)->isDict()) {
     action = LinkAction::parseAction(&obj1, catalog->getBaseURI());
     if (action->getKind() == actionRendition && page == 0) {
-      error (-1, "Invalid Rendition action: associated screen annotation without P");
+      error (errSyntaxError, -1, "Invalid Rendition action: associated screen annotation without P");
       delete action;
       action = NULL;
       ok = gFalse;
@@ -4391,7 +4391,7 @@ void AnnotPolygon::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) {
     vertices = new AnnotPath(obj1.getArray());
   } else {
     vertices = new AnnotPath();
-    error(-1, "Bad Annot Polygon Vertices");
+    error(errSyntaxError, -1, "Bad Annot Polygon Vertices");
     ok = gFalse;
   }
   obj1.free();
@@ -4557,7 +4557,7 @@ void AnnotInk::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) {
   } else {
     inkListLength = 0;
     inkList = NULL;
-    error(-1, "Bad Annot Ink List");
+    error(errSyntaxError, -1, "Bad Annot Ink List");
     ok = gFalse;
   }
   obj1.free();
@@ -4600,7 +4600,7 @@ void AnnotFileAttachment::initialize(XRef *xrefA, Catalog *catalog, Dict* dict)
   if (dict->lookup("FS", &obj1)->isDict() || dict->lookup("FS", &obj1)->isString()) {
     obj1.copy(&file);
   } else {
-    error(-1, "Bad Annot File Attachment");
+    error(errSyntaxError, -1, "Bad Annot File Attachment");
     ok = gFalse;
   }
   obj1.free();
@@ -4815,7 +4815,7 @@ void AnnotSound::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) {
 
   sound = Sound::parseSound(dict->lookup("Sound", &obj1));
   if (!sound) {
-    error(-1, "Bad Annot Sound");
+    error(errSyntaxError, -1, "Bad Annot Sound");
     ok = gFalse;
   }
   obj1.free();
diff --git a/poppler/ArthurOutputDev.cc b/poppler/ArthurOutputDev.cc
index cb3ea1c..a1300b5 100644
--- a/poppler/ArthurOutputDev.cc
+++ b/poppler/ArthurOutputDev.cc
@@ -322,7 +322,7 @@ void ArthurOutputDev::updateFont(GfxState *state)
         dfp = globalParams->getDisplayFont(gfxFont);
       }
       if (!dfp) {
-	error(-1, "Couldn't find a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't find a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -353,7 +353,7 @@ void ArthurOutputDev::updateFont(GfxState *state)
 			   id,
 			   fontsrc,
 			   (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -364,7 +364,7 @@ void ArthurOutputDev::updateFont(GfxState *state)
 			   id,
 			   fontsrc,
 			   (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -375,7 +375,7 @@ void ArthurOutputDev::updateFont(GfxState *state)
 			   id,
 			   fontsrc,
 			   (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -399,7 +399,7 @@ void ArthurOutputDev::updateFont(GfxState *state)
 			   id,
 			   fontsrc,
 			   codeToGID, n))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -410,7 +410,7 @@ void ArthurOutputDev::updateFont(GfxState *state)
       if (!(fontFile = m_fontEngine->loadCIDFont(
 			   id,
 			   fontsrc))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -420,7 +420,7 @@ void ArthurOutputDev::updateFont(GfxState *state)
       if (!(fontFile = m_fontEngine->loadOpenTypeCFFFont(
 			   id,
 			   fontsrc))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -451,7 +451,7 @@ void ArthurOutputDev::updateFont(GfxState *state)
 			   id,
 			   fontsrc,
 			   codeToGID, n, faceIndex))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
diff --git a/poppler/CMap.cc b/poppler/CMap.cc
index 0e861c0..884b5c5 100644
--- a/poppler/CMap.cc
+++ b/poppler/CMap.cc
@@ -85,8 +85,8 @@ CMap *CMap::parse(CMapCache *cache, GooString *collectionA,
         return new CMap(collectionA->copy(), cMapNameA->copy(), 1);
       }
 
-      error(-1, "Couldn't find '%s' CMap file for '%s' collection",
-	    cMapNameA->getCString(), collectionA->getCString());
+      error(errSyntaxError, -1, "Couldn't find '{0:t}' CMap file for '{1:t}' collection",
+	    cMapNameA, collectionA);
       return NULL;
     }
     pst = new PSTokenizer(&getCharFromFile, f);
@@ -111,7 +111,7 @@ CMap *CMap::parse(CMapCache *cache, GooString *collectionA,
 	}
 	if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
 	    !strcmp(tok2, "endcodespacerange")) {
-	  error(-1, "Illegal entry in codespacerange block in CMap");
+	  error(errSyntaxError, -1, "Illegal entry in codespacerange block in CMap");
 	  break;
 	}
 	if (tok1[0] == '<' && tok2[0] == '<' &&
@@ -131,17 +131,17 @@ CMap *CMap::parse(CMapCache *cache, GooString *collectionA,
 	}
 	if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
 	    !strcmp(tok2, "endcidchar")) {
-	  error(-1, "Illegal entry in cidchar block in CMap");
+	  error(errSyntaxError, -1, "Illegal entry in cidchar block in CMap");
 	  break;
 	}
 	if (!(tok1[0] == '<' && tok1[n1 - 1] == '>' &&
 	      n1 >= 4 && (n1 & 1) == 0)) {
-	  error(-1, "Illegal entry in cidchar block in CMap");
+	  error(errSyntaxError, -1, "Illegal entry in cidchar block in CMap");
 	  continue;
 	}
 	tok1[n1 - 1] = '\0';
 	if (sscanf(tok1 + 1, "%x", &code) != 1) {
-	  error(-1, "Illegal entry in cidchar block in CMap");
+	  error(errSyntaxError, -1, "Illegal entry in cidchar block in CMap");
 	  continue;
 	}
 	n1 = (n1 - 2) / 2;
@@ -157,7 +157,7 @@ CMap *CMap::parse(CMapCache *cache, GooString *collectionA,
 	    !strcmp(tok2, "endcidrange") ||
 	    !pst->getToken(tok3, sizeof(tok3), &n3) ||
 	    !strcmp(tok3, "endcidrange")) {
-	  error(-1, "Illegal entry in cidrange block in CMap");
+	  error(errSyntaxError, -1, "Illegal entry in cidrange block in CMap");
 	  break;
 	}
 	if (tok1[0] == '<' && tok2[0] == '<' &&
@@ -242,7 +242,7 @@ void CMap::copyVector(CMapVectorEntry *dest, CMapVectorEntry *src) {
       copyVector(dest[i].vector, src[i].vector);
     } else {
       if (dest[i].isVector) {
-	error(-1, "Collision in usecmap");
+	error(errSyntaxError, -1, "Collision in usecmap");
       } else {
 	dest[i].cid = src[i].cid;
       }
@@ -285,8 +285,9 @@ void CMap::addCIDs(Guint start, Guint end, Guint nBytes, CID firstCID) {
   for (i = nBytes - 1; i >= 1; --i) {
     byte = (start >> (8 * i)) & 0xff;
     if (!vec[byte].isVector) {
-      error(-1, "Invalid CID (%0*x - %0*x) in CMap",
-	    2*nBytes, start, 2*nBytes, end);
+      error(errSyntaxError, -1,
+	    "Invalid CID ({0:x} - {1:x} [{2:d} bytes]) in CMap",
+	    start, end, nBytes);
       return;
     }
     vec = vec[byte].vector;
@@ -294,8 +295,9 @@ void CMap::addCIDs(Guint start, Guint end, Guint nBytes, CID firstCID) {
   cid = firstCID;
   for (byte = (int)(start & 0xff); byte <= (int)(end & 0xff); ++byte) {
     if (vec[byte].isVector) {
-      error(-1, "Invalid CID (%0*x - %0*x) in CMap",
-	    2*nBytes, start, 2*nBytes, end);
+      error(errSyntaxError, -1,
+	    "Invalid CID ({0:x} - {1:x} [{2:d} bytes]) in CMap",
+	    start, end, nBytes);
     } else {
       vec[byte].cid = cid;
     }
diff --git a/poppler/CachedFile.cc b/poppler/CachedFile.cc
index 3933830..4c20dae 100644
--- a/poppler/CachedFile.cc
+++ b/poppler/CachedFile.cc
@@ -33,7 +33,7 @@ CachedFile::CachedFile(CachedFileLoader *cachedFileLoaderA, GooString *uriA)
     chunks->resize(length/CachedFileChunkSize + 1);
   }
   else {
-    error(-1, "Failed to initialize file cache for '%s'.", uri->getCString());
+    error(errInternal, -1, "Failed to initialize file cache for '{0:t}'.", uri);
     chunks->resize(0);
   }
 }
diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc
index 95ac60d..b827465 100644
--- a/poppler/CairoFontEngine.cc
+++ b/poppler/CairoFontEngine.cc
@@ -425,7 +425,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref,
       dfp = globalParams->getDisplayFont(gfxFont);
     }
     if (!dfp) {
-      error(-1, "Couldn't find a font for '%s'",
+      error(errSyntaxError, -1, "Couldn't find a font for '{0:s}'",
 	    gfxFont->getName() ? gfxFont->getName()->getCString()
 	    : "(unnamed)");
       goto err2;
@@ -452,7 +452,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref,
   case fontType1C:
   case fontType1COT:
     if (! _ft_new_face (lib, fileNameC, font_data, font_data_len, &face, &font_face)) {
-      error(-1, "could not create type1 face");
+      error(errSyntaxError, -1, "could not create type1 face");
       goto err2;
     }
     
@@ -498,7 +498,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref,
       ff = FoFiTrueType::load(fileNameC);
     }
     if (! ff) {
-      error(-1, "failed to load truetype font\n");
+      error(errSyntaxError, -1, "failed to load truetype font\n");
       goto err2;
     }
     /* This might be set already for the CIDType2 case */
@@ -508,7 +508,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref,
     }
     delete ff;
     if (! _ft_new_face (lib, fileNameC, font_data, font_data_len, &face, &font_face)) {
-      error(-1, "could not create truetype face\n");
+      error(errSyntaxError, -1, "could not create truetype face\n");
       goto err2;
     }
     break;
@@ -535,7 +535,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref,
     if (! _ft_new_face (lib, fileNameC, font_data, font_data_len, &face, &font_face)) {
       gfree(codeToGID);
       codeToGID = NULL;
-      error(-1, "could not create cid face\n");
+      error(errSyntaxError, -1, "could not create cid face\n");
       goto err2;
     }
     break;
diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc
index a8c2e39..c6c77eb 100644
--- a/poppler/Catalog.cc
+++ b/poppler/Catalog.cc
@@ -87,7 +87,7 @@ Catalog::Catalog(XRef *xrefA) {
 
   xref->getCatalog(&catDict);
   if (!catDict.isDict()) {
-    error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
+    error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
     goto err1;
   }
   // get the AcroForm dictionary
@@ -186,7 +186,7 @@ GooString *Catalog::readMetadata() {
     if (catDict.isDict()) {
       catDict.dictLookup("Metadata", &metadata);
     } else {
-      error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
+      error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
       metadata.initNull();
     }
     catDict.free();
@@ -197,7 +197,7 @@ GooString *Catalog::readMetadata() {
   }
   dict = metadata.streamGetDict();
   if (!dict->lookup("Subtype", &obj)->isName("XML")) {
-    error(-1, "Unknown Metadata type: '%s'",
+    error(errSyntaxWarning, -1, "Unknown Metadata type: '{0:s}'",
 	  obj.isName() ? obj.getName() : "???");
   }
   obj.free();
@@ -246,13 +246,13 @@ GBool Catalog::cachePageTree(int page)
         pagesRef = pagesDictRef.getRef();
         pagesDictRef.free();
       } else {
-        error(-1, "Catalog dictionary does not contain a valid \"Pages\" entry");
+        error(errSyntaxError, -1, "Catalog dictionary does not contain a valid \"Pages\" entry");
         pagesDictRef.free();
         catDict.free();
         return gFalse;
       }
     } else {
-      error(-1, "Could not find catalog dictionary");
+      error(errSyntaxError, -1, "Could not find catalog dictionary");
       catDict.free();
       return gFalse;
     }
@@ -268,7 +268,7 @@ GBool Catalog::cachePageTree(int page)
       obj.free();
     }
     else {
-      error(-1, "Top-level pages object is wrong type (%s)", obj.getTypeName());
+      error(errSyntaxError, -1, "Top-level pages object is wrong type ({0:s})", obj.getTypeName());
       obj.free();
       return gFalse;
     }
@@ -304,7 +304,7 @@ GBool Catalog::cachePageTree(int page)
     Object kids;
     pagesDict->lookup("Kids", &kids);
     if (!kids.isArray()) {
-      error(-1, "Kids object (page %d) is wrong type (%s)",
+      error(errSyntaxError, -1, "Kids object (page {0:d}) is wrong type ({1:s})",
             lastCachedPage+1, kids.getTypeName());
       kids.free();
       return gFalse;
@@ -328,7 +328,7 @@ GBool Catalog::cachePageTree(int page)
     Object kidRef;
     kids.arrayGetNF(kidsIdx, &kidRef);
     if (!kidRef.isRef()) {
-      error(-1, "Kid object (page %d) is not an indirect reference (%s)",
+      error(errSyntaxError, -1, "Kid object (page {0:d}) is not an indirect reference ({1:s})",
             lastCachedPage+1, kidRef.getTypeName());
       kidRef.free();
       kids.free();
@@ -343,7 +343,7 @@ GBool Catalog::cachePageTree(int page)
       }
     }
     if (loop) {
-      error(-1, "Loop in Pages tree");
+      error(errSyntaxError, -1, "Loop in Pages tree");
       kidRef.free();
       kids.free();
       kidsIdxList->back()++;
@@ -358,7 +358,7 @@ GBool Catalog::cachePageTree(int page)
       Page *p = new Page(xref, lastCachedPage+1, kid.getDict(),
                      kidRef.getRef(), attrs, form);
       if (!p->isOk()) {
-        error(-1, "Failed to create page (page %d)", lastCachedPage+1);
+        error(errSyntaxError, -1, "Failed to create page (page {0:d})", lastCachedPage+1);
         delete p;
         kidRef.free();
         kid.free();
@@ -366,7 +366,7 @@ GBool Catalog::cachePageTree(int page)
       }
 
       if (lastCachedPage >= numPages) {
-        error(-1, "Page count in top-level pages object is incorrect");
+        error(errSyntaxError, -1, "Page count in top-level pages object is incorrect");
         kidRef.free();
         kid.free();
         return gFalse;
@@ -388,7 +388,7 @@ GBool Catalog::cachePageTree(int page)
       pagesList->push_back(kid.getDict());
       kidsIdxList->push_back(0);
     } else {
-      error(-1, "Kid object (page %d) is wrong type (%s)",
+      error(errSyntaxError, -1, "Kid object (page {0:d}) is wrong type ({1:s})",
             lastCachedPage+1, kid.getTypeName());
       kidsIdxList->back()++;
     }
@@ -441,10 +441,10 @@ LinkDest *Catalog::findDest(GooString *name) {
     if (obj1.dictLookup("D", &obj2)->isArray())
       dest = new LinkDest(obj2.getArray());
     else
-      error(-1, "Bad named destination value");
+      error(errSyntaxWarning, -1, "Bad named destination value");
     obj2.free();
   } else {
-    error(-1, "Bad named destination value");
+    error(errSyntaxWarning, -1, "Bad named destination value");
   }
   obj1.free();
   if (dest && !dest->isOk()) {
@@ -520,7 +520,7 @@ Catalog::PageMode Catalog::getPageMode() {
 
     xref->getCatalog(&catDict);
     if (!catDict.isDict()) {
-      error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
+      error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
       catDict.free();
       return pageMode;
     }
@@ -555,7 +555,7 @@ Catalog::PageLayout Catalog::getPageLayout() {
 
     xref->getCatalog(&catDict);
     if (!catDict.isDict()) {
-      error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
+      error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
       catDict.free();
       return pageLayout;
     }
@@ -607,7 +607,7 @@ NameTree::Entry::Entry(Array *array, int index) {
         name.append(aux.getString());
       }
       else
-        error(-1, "Invalid page tree");
+        error(errSyntaxError, -1, "Invalid page tree");
     }
 }
 
@@ -752,7 +752,7 @@ int Catalog::getNumPages()
 
     xref->getCatalog(&catDict);
     if (!catDict.isDict()) {
-      error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
+      error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
       catDict.free();
       return 0;
     }
@@ -762,7 +762,7 @@ int Catalog::getNumPages()
     // This should really be isDict("Pages"), but I've seen at least one
     // PDF file where the /Type entry is missing.
     if (!pagesDict.isDict()) {
-      error(-1, "Top-level pages object is wrong type (%s)",
+      error(errSyntaxError, -1, "Top-level pages object is wrong type ({0:s})",
           pagesDict.getTypeName());
       pagesDict.free();
       return 0;
@@ -771,7 +771,7 @@ int Catalog::getNumPages()
     pagesDict.dictLookup("Count", &obj);
     // some PDF files actually use real numbers here ("/Count 9.0")
     if (!obj.isNum()) {
-      error(-1, "Page count in top-level pages object is wrong type (%s)",
+      error(errSyntaxError, -1, "Page count in top-level pages object is wrong type ({0:s})",
          obj.getTypeName());
       numPages = 0;
     } else {
@@ -793,7 +793,7 @@ PageLabelInfo *Catalog::getPageLabelInfo()
 
     xref->getCatalog(&catDict);
     if (!catDict.isDict()) {
-      error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
+      error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
       catDict.free();
       return NULL;
     }
@@ -818,7 +818,7 @@ Object *Catalog::getStructTreeRoot()
      if (catDict.isDict()) {
        catDict.dictLookup("StructTreeRoot", &structTreeRoot);
      } else {
-       error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
+       error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
        structTreeRoot.initNull();
      }
      catDict.free();
@@ -837,7 +837,7 @@ Object *Catalog::getOutline()
      if (catDict.isDict()) {
        catDict.dictLookup("Outlines", &outline);
      } else {
-       error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
+       error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
        outline.initNull();
      }
      catDict.free();
@@ -856,7 +856,7 @@ Object *Catalog::getDests()
      if (catDict.isDict()) {
        catDict.dictLookup("Dests", &dests);
      } else {
-       error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
+       error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
        dests.initNull();
      }
      catDict.free();
@@ -897,7 +897,7 @@ Object *Catalog::getNames()
      if (catDict.isDict()) {
        catDict.dictLookup("Names", &names);
      } else {
-       error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
+       error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
        names.initNull();
      }
      catDict.free();
diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc
index 3cfa402..b4f2f18 100644
--- a/poppler/CharCodeToUnicode.cc
+++ b/poppler/CharCodeToUnicode.cc
@@ -83,8 +83,8 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GooString *fileName,
   CharCodeToUnicode *ctu;
 
   if (!(f = fopen(fileName->getCString(), "r"))) {
-    error(-1, "Couldn't open cidToUnicode file '%s'",
-	  fileName->getCString());
+    error(errIO, -1, "Couldn't open cidToUnicode file '{0:t}'",
+	  fileName);
     return NULL;
   }
 
@@ -100,8 +100,8 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GooString *fileName,
     if (sscanf(buf, "%x", &u) == 1) {
       mapA[mapLenA] = u;
     } else {
-      error(-1, "Bad line (%d) in cidToUnicode file '%s'",
-	    (int)(mapLenA + 1), fileName->getCString());
+      error(errSyntaxWarning, -1, "Bad line ({0:d}) in cidToUnicode file '{1:t}'",
+	    (int)(mapLenA + 1), fileName);
       mapA[mapLenA] = 0;
     }
     ++mapLenA;
@@ -131,8 +131,8 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(
 
   if (!(f = fopen(fileName->getCString(), "r"))) {
     gfree(uBuf);
-    error(-1, "Couldn't open unicodeToUnicode file '%s'",
-	  fileName->getCString());
+    error(errIO, -1, "Couldn't open unicodeToUnicode file '{0:t}'",
+	  fileName);
     return NULL;
   }
 
@@ -148,8 +148,8 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(
     ++line;
     if (!(tok = strtok_r(buf, " \t\r\n", &tokptr)) ||
 	sscanf(tok, "%x", &u0) != 1) {
-      error(-1, "Bad line (%d) in unicodeToUnicode file '%s'",
-	    line, fileName->getCString());
+      error(errSyntaxWarning, -1, "Bad line ({0:d}) in unicodeToUnicode file '{1:t}'",
+	    line, fileName);
       continue;
     }
     n = 0;
@@ -160,15 +160,15 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(
         uBuf = (Unicode *)greallocn(uBuf, uBufSize, sizeof(Unicode));
       }
       if (sscanf(tok, "%x", &uBuf[n]) != 1) {
-	error(-1, "Bad line (%d) in unicodeToUnicode file '%s'",
-	      line, fileName->getCString());
+	error(errSyntaxWarning, -1, "Bad line ({0:d}) in unicodeToUnicode file '{1:t}'",
+	      line, fileName);
 	break;
       }
       ++n;
     }
     if (n < 1) {
-      error(-1, "Bad line (%d) in unicodeToUnicode file '%s'",
-	    line, fileName->getCString());
+      error(errSyntaxWarning, -1, "Bad line ({0:d}) in unicodeToUnicode file '{1:t}'",
+	    line, fileName);
       continue;
     }
     if (u0 >= size) {
@@ -233,8 +233,8 @@ CharCodeToUnicode *CharCodeToUnicode::parseCMapFromFile(GooString *fileName,
     ctu->parseCMap1(&getCharFromFile, f, nBits);
     fclose(f);
   } else {
-    error(-1, "Couldn't find ToUnicode CMap file for '%s'",
-	  fileName->getCString());
+    error(errSyntaxError, -1, "Couldn't find ToUnicode CMap file for '{0:t}'",
+	  fileName);
   }
   return ctu;
 }
@@ -267,8 +267,8 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
 	  parseCMap1(&getCharFromFile, f, nBits);
 	  fclose(f);
 	} else {
-	  error(-1, "Couldn't find ToUnicode CMap file for '%s'",
-		name->getCString());
+	  error(errSyntaxError, -1, "Couldn't find ToUnicode CMap file for '{0:t}'",
+		name);
 	}
 	delete name;
       }
@@ -280,20 +280,20 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
 	}
 	if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
 	    !strcmp(tok2, "endbfchar")) {
-	  error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
+	  error(errSyntaxWarning, -1, "Illegal entry in bfchar block in ToUnicode CMap");
 	  break;
 	}
 	if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
 	      tok2[0] == '<' && tok2[n2 - 1] == '>')) {
 	  if (!(n1 == 4 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0' &&
 	        tok2[0] == '<' && tok2[n2 - 1] == '>')) {
-	    error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
+	    error(errSyntaxWarning, -1, "Illegal entry in bfchar block in ToUnicode CMap");
 	    continue;
 	  }
 	}
 	tok1[n1 - 1] = tok2[n2 - 1] = '\0';
 	if (sscanf(tok1 + 1, "%x", &code1) != 1) {
-	  error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
+	  error(errSyntaxWarning, -1, "Illegal entry in bfchar block in ToUnicode CMap");
 	  continue;
 	}
 	addMapping(code1, tok2 + 1, n2 - 2, 0);
@@ -308,20 +308,20 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
 	    !strcmp(tok2, "endbfrange") ||
 	    !pst->getToken(tok3, sizeof(tok3), &n3) ||
 	    !strcmp(tok3, "endbfrange")) {
-	  error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
+	  error(errSyntaxWarning, -1, "Illegal entry in bfrange block in ToUnicode CMap");
 	  break;
 	}
 	if (!(((n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>') ||
 	       (n1 == 4 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0')) &&
 	      ((n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>') ||
 	       (n2 == 4 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0')))) {
-	  error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
+	  error(errSyntaxWarning, -1, "Illegal entry in bfrange block in ToUnicode CMap");
 	  continue;
 	}
 	tok1[n1 - 1] = tok2[n2 - 1] = '\0';
 	if (sscanf(tok1 + 1, "%x", &code1) != 1 ||
 	    sscanf(tok2 + 1, "%x", &code2) != 1) {
-	  error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
+	  error(errSyntaxWarning, -1, "Illegal entry in bfrange block in ToUnicode CMap");
 	  continue;
 	}
 	if (!strcmp(tok3, "[")) {
@@ -335,7 +335,7 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
 	      tok1[n1 - 1] = '\0';
 	      addMapping(code1 + i, tok1 + 1, n1 - 2, 0);
 	    } else {
-	      error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
+	      error(errSyntaxWarning, -1, "Illegal entry in bfrange block in ToUnicode CMap");
 	    }
 	    ++i;
 	  }
@@ -346,7 +346,7 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
 	  }
 
 	} else {
-	  error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
+	  error(errSyntaxWarning, -1, "Illegal entry in bfrange block in ToUnicode CMap");
 	}
       }
       pst->getToken(tok1, sizeof(tok1), &n1);
@@ -368,7 +368,7 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
     oldLen = mapLen;
     mapLen = (code + 256) & ~255;
     if (unlikely(code >= mapLen)) {
-      error(-1, "Illegal code value in CharCodeToUnicode::addMapping");
+      error(errSyntaxWarning, -1, "Illegal code value in CharCodeToUnicode::addMapping");
       return;
     } else {
       map = (Unicode *)greallocn(map, mapLen, sizeof(Unicode));
@@ -379,7 +379,7 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
   }
   if (n <= 4) {
     if (sscanf(uStr, "%x", &u) != 1) {
-      error(-1, "Illegal entry in ToUnicode CMap");
+      error(errSyntaxWarning, -1, "Illegal entry in ToUnicode CMap");
       return;
     }
     map[code] = u + offset;
@@ -397,7 +397,7 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
       strncpy(uHex, uStr + j*4, 4);
       uHex[4] = '\0';
       if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) {
-	error(-1, "Illegal entry in ToUnicode CMap");
+	error(errSyntaxWarning, -1, "Illegal entry in ToUnicode CMap");
       }
     }
     sMap[sMapLen].u[sMap[sMapLen].len - 1] += offset;
diff --git a/poppler/CurlCachedFile.cc b/poppler/CurlCachedFile.cc
index 26e59e3..af4c2b6 100644
--- a/poppler/CurlCachedFile.cc
+++ b/poppler/CurlCachedFile.cc
@@ -56,7 +56,7 @@ CurlCachedFileLoader::init(GooString *urlA, CachedFile *cachedFileA)
      curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength);
      size = contentLength;
   } else {
-     error(-1, "Failed to get size of '%s'.", url->getCString());
+     error(errInternal, -1, "Failed to get size of '{0:t}'.", url);
      size = -1;
   }
   curl_easy_reset(curl);
diff --git a/poppler/DCTStream.cc b/poppler/DCTStream.cc
index a7422db..90a1377 100644
--- a/poppler/DCTStream.cc
+++ b/poppler/DCTStream.cc
@@ -125,7 +125,7 @@ void DCTStream::reset() {
       c = str->getChar();
       if (c == -1)
       {
-        error(-1, "Could not find start of jpeg data");
+        error(errSyntaxError, -1, "Could not find start of jpeg data");
         return;
       }
       if (c != 0xFF) c = 0;
diff --git a/poppler/Decrypt.cc b/poppler/Decrypt.cc
index 4042eba..24af996 100644
--- a/poppler/Decrypt.cc
+++ b/poppler/Decrypt.cc
@@ -844,7 +844,7 @@ static void aes256DecryptBlock(DecryptAES256State *s, Guchar *in, GBool last) {
     s->bufIdx = n;
     if (n > 16)
     {
-      error(-1, "Reducing bufIdx from %d to 16 to not crash", n);
+      error(errSyntaxError, -1, "Reducing bufIdx from {0:d} to 16 to not crash", n);
       s->bufIdx = 16;
     }
   }
diff --git a/poppler/Error.cc b/poppler/Error.cc
index 7a2db19..782346b 100644
--- a/poppler/Error.cc
+++ b/poppler/Error.cc
@@ -31,37 +31,56 @@
 #include <stdio.h>
 #include <stddef.h>
 #include <stdarg.h>
+#include "GooString.h"
 #include "GlobalParams.h"
 #include "Error.h"
 
-static void defaultErrorFunction(int pos, const char *msg, va_list args)
-{
-  if (pos >= 0) {
-    fprintf(stderr, "Error (%d): ", pos);
-  } else {
-    fprintf(stderr, "Error: ");
-  }
-  vfprintf(stderr, msg, args);
-  fprintf(stderr, "\n");
-  fflush(stderr);
-}
+static const char *errorCategoryNames[] = {
+  "Syntax Warning",
+  "Syntax Error",
+  "Config Error",
+  "Command Line Error",
+  "I/O Error",
+  "Permission Error",
+  "Unimplemented Feature",
+  "Internal Error"
+};
 
-static void (*errorFunction)(int, const char *, va_list args) = defaultErrorFunction;
+static void (*errorCbk)(void *data, ErrorCategory category,
+			int pos, char *msg) = NULL;
+static void *errorCbkData = NULL;
 
-void setErrorFunction(void (* f)(int, const char *, va_list args))
-{
-    errorFunction = f;
+void setErrorCallback(void (*cbk)(void *data, ErrorCategory category,
+				  int pos, char *msg),
+		      void *data) {
+  errorCbk = cbk;
+  errorCbkData = data;
 }
 
-void CDECL error(int pos, const char *msg, ...) {
+void CDECL error(ErrorCategory category, int pos, const char *msg, ...) {
   va_list args;
+  GooString *s;
+
   // NB: this can be called before the globalParams object is created
-  if (globalParams && globalParams->getErrQuiet()) {
+  if (!errorCbk && globalParams && globalParams->getErrQuiet()) {
     return;
   }
   va_start(args, msg);
-  (*errorFunction)(pos, msg, args);
+  s = GooString::formatv(msg, args);
   va_end(args);
+  if (errorCbk) {
+    (*errorCbk)(errorCbkData, category, pos, s->getCString());
+  } else {
+    if (pos >= 0) {
+      fprintf(stderr, "%s (%d): %s\n",
+	      errorCategoryNames[category], pos, s->getCString());
+    } else {
+      fprintf(stderr, "%s: %s\n",
+	      errorCategoryNames[category], s->getCString());
+    }
+    fflush(stderr);
+  }
+  delete s;
 }
 
 void warning(const char *msg, ...) {
diff --git a/poppler/Error.h b/poppler/Error.h
index da7913c..6cd22b4 100644
--- a/poppler/Error.h
+++ b/poppler/Error.h
@@ -32,9 +32,26 @@
 #include <stdarg.h>
 #include "poppler-config.h"
 
-extern void CDECL error(int pos, const char *msg, ...) GCC_PRINTF_FORMAT (2, 3);
-void warning(const char *msg, ...) GCC_PRINTF_FORMAT (1, 2);
+enum ErrorCategory {
+  errSyntaxWarning,    // PDF syntax error which can be worked around;
+                       //   output will probably be correct
+  errSyntaxError,      // PDF syntax error which can be worked around;
+                       //   output will probably be incorrect
+  errConfig,           // error in Xpdf config info (xpdfrc file, etc.)
+  errCommandLine,      // error in user-supplied parameters, action not
+                       //   allowed, etc. (only used by command-line tools)
+  errIO,               // error in file I/O
+  errNotAllowed,       // action not allowed by PDF permission bits
+  errUnimplemented,    // unimplemented PDF feature - display will be
+                       //   incorrect
+  errInternal          // internal error - malfunction within the Xpdf code
+};
+
+extern void setErrorCallback(void (*cbk)(void *data, ErrorCategory category,
+					 int pos, char *msg),
+			     void *data);
 
-void setErrorFunction(void (* f)(int , const char *, va_list args));
+extern void CDECL error(ErrorCategory category, int pos, const char *msg, ...);
+void warning(const char *msg, ...) GCC_PRINTF_FORMAT (1, 2);
 
 #endif
diff --git a/poppler/FileSpec.cc b/poppler/FileSpec.cc
index 7993ab5..0366acc 100644
--- a/poppler/FileSpec.cc
+++ b/poppler/FileSpec.cc
@@ -92,7 +92,7 @@ FileSpec::FileSpec(Object *fileSpecA)
   if (!getFileSpecName(fileSpecA, &obj1)) {
     ok = gFalse;
     obj1.free();
-    error(-1, "Invalid FileSpec");
+    error(errSyntaxError, -1, "Invalid FileSpec");
     return;
   }
 
@@ -104,7 +104,7 @@ FileSpec::FileSpec(Object *fileSpecA)
       if (!obj1.dictLookupNF("F", &fileStream)->isRef()) {
         ok = gFalse;
         fileStream.free();
-        error(-1, "Invalid FileSpec: Embedded file stream is not an indirect reference");
+        error(errSyntaxError, -1, "Invalid FileSpec: Embedded file stream is not an indirect reference");
         obj1.free();
         return;
       }
@@ -209,13 +209,13 @@ GBool getFileSpecNameForPlatform (Object *fileSpec, Object *fileName)
 #endif
 	if (!fileSpec->dictLookup(platform, fileName)->isString ()) {
 	  fileName->free();
-	  error(-1, "Illegal file spec");
+	  error(errSyntaxError, -1, "Illegal file spec");
 	  return gFalse;
 	}
       }
     }
   } else {
-    error(-1, "Illegal file spec");
+    error(errSyntaxError, -1, "Illegal file spec");
     return gFalse;
   }
 
diff --git a/poppler/Form.cc b/poppler/Form.cc
index 6137c34..80ff935 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -291,7 +291,7 @@ int FormWidgetText::getMaxLen () const
 void FormWidgetText::setContent(GooString* new_content)
 {
   if (isReadOnly()) {
-    error(-1, "FormWidgetText::setContentCopy called on a read only field\n");
+    error(errInternal, -1, "FormWidgetText::setContentCopy called on a read only field\n");
     return;
   }
 
@@ -312,7 +312,7 @@ FormWidgetChoice::~FormWidgetChoice()
 bool FormWidgetChoice::_checkRange (int i)
 {
   if (i < 0 || i >= parent->getNumChoices()) {
-    error(-1, "FormWidgetChoice::_checkRange i out of range : %i", i);
+    error(errInternal, -1, "FormWidgetChoice::_checkRange i out of range : {0:d}", i);
     return false;
   } 
   return true;
@@ -321,7 +321,7 @@ bool FormWidgetChoice::_checkRange (int i)
 void FormWidgetChoice::select (int i)
 {
   if (isReadOnly()) {
-    error(-1, "FormWidgetChoice::select called on a read only field\n");
+    error(errInternal, -1, "FormWidgetChoice::select called on a read only field\n");
     return;
   }
   if (!_checkRange(i)) return;
@@ -331,7 +331,7 @@ void FormWidgetChoice::select (int i)
 void FormWidgetChoice::toggle (int i)
 {
   if (isReadOnly()) {
-    error(-1, "FormWidgetChoice::toggle called on a read only field\n");
+    error(errInternal, -1, "FormWidgetChoice::toggle called on a read only field\n");
     return;
   }
   if (!_checkRange(i)) return;
@@ -341,7 +341,7 @@ void FormWidgetChoice::toggle (int i)
 void FormWidgetChoice::deselectAll ()
 {
   if (isReadOnly()) {
-    error(-1, "FormWidgetChoice::deselectAll called on a read only field\n");
+    error(errInternal, -1, "FormWidgetChoice::deselectAll called on a read only field\n");
     return;
   }
   parent->deselectAll();
@@ -350,7 +350,7 @@ void FormWidgetChoice::deselectAll ()
 GooString* FormWidgetChoice::getEditChoice ()
 {
   if (!hasEdit()) {
-    error(-1, "FormFieldChoice::getEditChoice called on a non-editable choice\n");
+    error(errInternal, -1, "FormFieldChoice::getEditChoice called on a non-editable choice\n");
     return NULL;
   }
   return parent->getEditChoice();
@@ -365,11 +365,11 @@ bool FormWidgetChoice::isSelected (int i)
 void FormWidgetChoice::setEditChoice (GooString* new_content)
 {
   if (isReadOnly()) {
-    error(-1, "FormWidgetText::setEditChoice called on a read only field\n");
+    error(errInternal, -1, "FormWidgetText::setEditChoice called on a read only field\n");
     return;
   }
   if (!hasEdit()) {
-    error(-1, "FormFieldChoice::setEditChoice : trying to edit an non-editable choice\n");
+    error(errInternal, -1, "FormFieldChoice::setEditChoice : trying to edit an non-editable choice\n");
     return;
   }
 
@@ -457,12 +457,12 @@ FormField::FormField(XRef* xrefA, Object *aobj, const Ref& aref, FormField *pare
       Object childRef, childObj;
 
       if (!obj1.arrayGetNF(i, &childRef)->isRef()) {
-        error (-1, "Invalid form field renference");
+        error (errSyntaxError, -1, "Invalid form field renference");
         childRef.free();
         continue;
       }
       if (!obj1.arrayGet(i, &childObj)->isDict()) {
-        error (-1, "Form field child is not a dictionary");
+        error (errSyntaxError, -1, "Form field child is not a dictionary");
         childObj.free();
         childRef.free();
         continue;
@@ -482,7 +482,7 @@ FormField::FormField(XRef* xrefA, Object *aobj, const Ref& aref, FormField *pare
           obj3.free();
 
           if (terminal) {
-            error(-1, "Field can't have both Widget AND Field as kids\n");
+            error(errSyntaxWarning, -1, "Field can't have both Widget AND Field as kids\n");
             continue;
           }
 
@@ -492,7 +492,7 @@ FormField::FormField(XRef* xrefA, Object *aobj, const Ref& aref, FormField *pare
         } else if (childObj.dictLookup("Subtype", &obj2)->isName("Widget")) {
           // Child is a widget annotation
           if (!terminal && numChildren > 0) {
-            error(-1, "Field can't have both Widget AND Field as kids\n");
+            error(errSyntaxWarning, -1, "Field can't have both Widget AND Field as kids\n");
             obj2.free();
             obj3.free();
             continue;
@@ -646,7 +646,7 @@ void FormField::_createWidget (Object *obj, Ref aref)
     widgets[numChildren-1] = new FormWidgetSignature(xref, obj, numChildren-1, aref, this);
     break;
   default:
-    error(-1, "SubType on non-terminal field, invalid document?");
+    error(errSyntaxWarning, -1, "SubType on non-terminal field, invalid document?");
     numChildren--;
     terminal = false;
   }
@@ -740,7 +740,7 @@ FormFieldButton::FormFieldButton(XRef *xrefA, Object *aobj, const Ref& ref, Form
       }
     } 
     if (flags & 0x1000000) { // 26 -> radiosInUnison
-      error(-1, "FormFieldButton:: radiosInUnison flag unimplemented, please report a bug with a testcase\n");
+      error(errUnimplemented, -1, "FormFieldButton:: radiosInUnison flag unimplemented, please report a bug with a testcase\n");
     } 
   }
 
@@ -796,7 +796,7 @@ void FormFieldButton::fillChildrenSiblingsID()
 GBool FormFieldButton::setState(char *state)
 {
   if (readOnly) {
-    error(-1, "FormFieldButton::setState called on a readOnly field\n");
+    error(errInternal, -1, "FormFieldButton::setState called on a readOnly field\n");
     return gFalse;
   }
 
@@ -1024,22 +1024,22 @@ FormFieldChoice::FormFieldChoice(XRef *xrefA, Object *aobj, const Ref& ref, Form
         Object obj3;
 
         if (obj2.arrayGetLength() < 2) {
-          error(-1, "FormWidgetChoice:: invalid Opt entry -- array's length < 2\n");
+          error(errSyntaxError, -1, "FormWidgetChoice:: invalid Opt entry -- array's length < 2\n");
           continue;
         }
         if (obj2.arrayGet(0, &obj3)->isString())
           choices[i].exportVal = obj3.getString()->copy();
         else
-          error(-1, "FormWidgetChoice:: invalid Opt entry -- exported value not a string\n");
+          error(errSyntaxError, -1, "FormWidgetChoice:: invalid Opt entry -- exported value not a string\n");
         obj3.free();
 
         if (obj2.arrayGet(1, &obj3)->isString())
           choices[i].optionName = obj3.getString()->copy();
         else
-          error(-1, "FormWidgetChoice:: invalid Opt entry -- choice name not a string\n");
+          error(errSyntaxError, -1, "FormWidgetChoice:: invalid Opt entry -- choice name not a string\n");
         obj3.free();
       } else {
-        error(-1, "FormWidgetChoice:: invalid %d Opt entry\n", i);
+        error(errSyntaxError, -1, "FormWidgetChoice:: invalid {0:d} Opt entry\n", i);
       }
       obj2.free();
     }
@@ -1289,14 +1289,14 @@ Form::Form(XRef *xrefA, Object* acroFormA)
       array->get(i, &obj2);
       array->getNF(i, &oref);
       if (!oref.isRef()) {
-        error(-1, "Direct object in rootFields");
+        error(errSyntaxWarning, -1, "Direct object in rootFields");
 	obj2.free();
 	oref.free();
         continue;
       }
 
       if (!obj2.isDict()) {
-        error(-1, "Reference in Fields array to an invalid or non existant object");
+        error(errSyntaxWarning, -1, "Reference in Fields array to an invalid or non existant object");
 	obj2.free();
 	oref.free();
 	continue;
@@ -1314,7 +1314,7 @@ Form::Form(XRef *xrefA, Object* acroFormA)
       oref.free();
     }
   } else {
-    error(-1, "Can't get Fields array\n");
+    error(errSyntaxError, -1, "Can't get Fields array\n");
   }
   obj1.free ();
 
diff --git a/poppler/Function.cc b/poppler/Function.cc
index b63ae81..d43105b 100644
--- a/poppler/Function.cc
+++ b/poppler/Function.cc
@@ -73,12 +73,12 @@ Function *Function::parse(Object *funcObj, std::set<int> *usedParents) {
   } else if (funcObj->isName("Identity")) {
     return new IdentityFunction();
   } else {
-    error(-1, "Expected function dictionary or stream");
+    error(errSyntaxError, -1, "Expected function dictionary or stream");
     return NULL;
   }
 
   if (!dict->lookup("FunctionType", &obj1)->isInt()) {
-    error(-1, "Function type is missing or wrong type");
+    error(errSyntaxError, -1, "Function type is missing or wrong type");
     obj1.free();
     return NULL;
   }
@@ -94,7 +94,7 @@ Function *Function::parse(Object *funcObj, std::set<int> *usedParents) {
   } else if (funcType == 4) {
     func = new PostScriptFunction(funcObj, dict);
   } else {
-    error(-1, "Unimplemented function type (%d)", funcType);
+    error(errSyntaxError, -1, "Unimplemented function type ({0:d})", funcType);
     return NULL;
   }
   if (!func->isOk()) {
@@ -111,26 +111,26 @@ GBool Function::init(Dict *dict) {
 
   //----- Domain
   if (!dict->lookup("Domain", &obj1)->isArray()) {
-    error(-1, "Function is missing domain");
+    error(errSyntaxError, -1, "Function is missing domain");
     goto err2;
   }
   m = obj1.arrayGetLength() / 2;
   if (m > funcMaxInputs) {
-    error(-1, "Functions with more than %d inputs are unsupported",
+    error(errSyntaxError, -1, "Functions with more than {0:d} inputs are unsupported",
 	  funcMaxInputs);
     goto err2;
   }
   for (i = 0; i < m; ++i) {
     obj1.arrayGet(2*i, &obj2);
     if (!obj2.isNum()) {
-      error(-1, "Illegal value in function domain array");
+      error(errSyntaxError, -1, "Illegal value in function domain array");
       goto err1;
     }
     domain[i][0] = obj2.getNum();
     obj2.free();
     obj1.arrayGet(2*i+1, &obj2);
     if (!obj2.isNum()) {
-      error(-1, "Illegal value in function domain array");
+      error(errSyntaxError, -1, "Illegal value in function domain array");
       goto err1;
     }
     domain[i][1] = obj2.getNum();
@@ -145,21 +145,21 @@ GBool Function::init(Dict *dict) {
     hasRange = gTrue;
     n = obj1.arrayGetLength() / 2;
     if (n > funcMaxOutputs) {
-      error(-1, "Functions with more than %d outputs are unsupported",
+      error(errSyntaxError, -1, "Functions with more than {0:d} outputs are unsupported",
 	    funcMaxOutputs);
       goto err2;
     }
     for (i = 0; i < n; ++i) {
       obj1.arrayGet(2*i, &obj2);
       if (!obj2.isNum()) {
-	error(-1, "Illegal value in function range array");
+	error(errSyntaxError, -1, "Illegal value in function range array");
 	goto err1;
       }
       range[i][0] = obj2.getNum();
       obj2.free();
       obj1.arrayGet(2*i+1, &obj2);
       if (!obj2.isNum()) {
-	error(-1, "Illegal value in function range array");
+	error(errSyntaxError, -1, "Illegal value in function range array");
 	goto err1;
       }
       range[i][1] = obj2.getNum();
@@ -229,11 +229,11 @@ SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
     goto err1;
   }
   if (!hasRange) {
-    error(-1, "Type 0 function is missing range");
+    error(errSyntaxError, -1, "Type 0 function is missing range");
     goto err1;
   }
   if (m > sampledFuncMaxInputs) {
-    error(-1, "Sampled functions with more than %d inputs are unsupported",
+    error(errSyntaxError, -1, "Sampled functions with more than {0:d} inputs are unsupported",
 	  sampledFuncMaxInputs);
     goto err1;
   }
@@ -243,7 +243,7 @@ SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
 
   //----- get the stream
   if (!funcObj->isStream()) {
-    error(-1, "Type 0 function isn't a stream");
+    error(errSyntaxError, -1, "Type 0 function isn't a stream");
     goto err1;
   }
   str = funcObj->getStream();
@@ -251,13 +251,13 @@ SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
   //----- Size
   if (!dict->lookup("Size", &obj1)->isArray() ||
       obj1.arrayGetLength() != m) {
-    error(-1, "Function has missing or invalid size array");
+    error(errSyntaxError, -1, "Function has missing or invalid size array");
     goto err2;
   }
   for (i = 0; i < m; ++i) {
     obj1.arrayGet(i, &obj2);
     if (!obj2.isInt()) {
-      error(-1, "Illegal value in function size array");
+      error(errSyntaxError, -1, "Illegal value in function size array");
       goto err3;
     }
     sampleSize[i] = obj2.getInt();
@@ -271,7 +271,7 @@ SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
 
   //----- BitsPerSample
   if (!dict->lookup("BitsPerSample", &obj1)->isInt()) {
-    error(-1, "Function has missing or invalid BitsPerSample");
+    error(errSyntaxError, -1, "Function has missing or invalid BitsPerSample");
     goto err2;
   }
   sampleBits = obj1.getInt();
@@ -284,14 +284,14 @@ SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
     for (i = 0; i < m; ++i) {
       obj1.arrayGet(2*i, &obj2);
       if (!obj2.isNum()) {
-	error(-1, "Illegal value in function encode array");
+	error(errSyntaxError, -1, "Illegal value in function encode array");
 	goto err3;
       }
       encode[i][0] = obj2.getNum();
       obj2.free();
       obj1.arrayGet(2*i+1, &obj2);
       if (!obj2.isNum()) {
-	error(-1, "Illegal value in function encode array");
+	error(errSyntaxError, -1, "Illegal value in function encode array");
 	goto err3;
       }
       encode[i][1] = obj2.getNum();
@@ -315,14 +315,14 @@ SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
     for (i = 0; i < n; ++i) {
       obj1.arrayGet(2*i, &obj2);
       if (!obj2.isNum()) {
-	error(-1, "Illegal value in function decode array");
+	error(errSyntaxError, -1, "Illegal value in function decode array");
 	goto err3;
       }
       decode[i][0] = obj2.getNum();
       obj2.free();
       obj1.arrayGet(2*i+1, &obj2);
       if (!obj2.isNum()) {
-	error(-1, "Illegal value in function decode array");
+	error(errSyntaxError, -1, "Illegal value in function decode array");
 	goto err3;
       }
       decode[i][1] = obj2.getNum();
@@ -467,21 +467,21 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
     goto err1;
   }
   if (m != 1) {
-    error(-1, "Exponential function with more than one input");
+    error(errSyntaxError, -1, "Exponential function with more than one input");
     goto err1;
   }
 
   //----- C0
   if (dict->lookup("C0", &obj1)->isArray()) {
     if (hasRange && obj1.arrayGetLength() != n) {
-      error(-1, "Function's C0 array is wrong length");
+      error(errSyntaxError, -1, "Function's C0 array is wrong length");
       goto err2;
     }
     n = obj1.arrayGetLength();
     for (i = 0; i < n; ++i) {
       obj1.arrayGet(i, &obj2);
       if (!obj2.isNum()) {
-	error(-1, "Illegal value in function C0 array");
+	error(errSyntaxError, -1, "Illegal value in function C0 array");
 	goto err3;
       }
       c0[i] = obj2.getNum();
@@ -489,7 +489,7 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
     }
   } else {
     if (hasRange && n != 1) {
-      error(-1, "Function's C0 array is wrong length");
+      error(errSyntaxError, -1, "Function's C0 array is wrong length");
       goto err2;
     }
     n = 1;
@@ -500,13 +500,13 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
   //----- C1
   if (dict->lookup("C1", &obj1)->isArray()) {
     if (obj1.arrayGetLength() != n) {
-      error(-1, "Function's C1 array is wrong length");
+      error(errSyntaxError, -1, "Function's C1 array is wrong length");
       goto err2;
     }
     for (i = 0; i < n; ++i) {
       obj1.arrayGet(i, &obj2);
       if (!obj2.isNum()) {
-	error(-1, "Illegal value in function C1 array");
+	error(errSyntaxError, -1, "Illegal value in function C1 array");
 	goto err3;
       }
       c1[i] = obj2.getNum();
@@ -514,7 +514,7 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
     }
   } else {
     if (n != 1) {
-      error(-1, "Function's C1 array is wrong length");
+      error(errSyntaxError, -1, "Function's C1 array is wrong length");
       goto err2;
     }
     c1[0] = 1;
@@ -523,7 +523,7 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
 
   //----- N (exponent)
   if (!dict->lookup("N", &obj1)->isNum()) {
-    error(-1, "Function has missing or invalid N");
+    error(errSyntaxError, -1, "Function has missing or invalid N");
     goto err2;
   }
   e = obj1.getNum();
@@ -591,13 +591,13 @@ StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict, std::set<int>
     goto err1;
   }
   if (m != 1) {
-    error(-1, "Stitching function with more than one input");
+    error(errSyntaxError, -1, "Stitching function with more than one input");
     goto err1;
   }
 
   //----- Functions
   if (!dict->lookup("Functions", &obj1)->isArray()) {
-    error(-1, "Missing 'Functions' entry in stitching function");
+    error(errSyntaxError, -1, "Missing 'Functions' entry in stitching function");
     goto err1;
   }
   k = obj1.arrayGetLength();
@@ -626,7 +626,8 @@ StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict, std::set<int>
     }
     if (i > 0 && (funcs[i]->getInputSize() != 1 ||
 		  funcs[i]->getOutputSize() != funcs[0]->getOutputSize())) {
-      error(-1, "Incompatible subfunctions in stitching function");
+      error(errSyntaxError, -1,
+	    "Incompatible subfunctions in stitching function");
       goto err2;
     }
     obj2.free();
@@ -636,13 +637,13 @@ StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict, std::set<int>
   //----- Bounds
   if (!dict->lookup("Bounds", &obj1)->isArray() ||
       obj1.arrayGetLength() != k - 1) {
-    error(-1, "Missing or invalid 'Bounds' entry in stitching function");
+    error(errSyntaxError, -1, "Missing or invalid 'Bounds' entry in stitching function");
     goto err1;
   }
   bounds[0] = domain[0][0];
   for (i = 1; i < k; ++i) {
     if (!obj1.arrayGet(i - 1, &obj2)->isNum()) {
-      error(-1, "Invalid type in 'Bounds' array in stitching function");
+      error(errSyntaxError, -1, "Invalid type in 'Bounds' array in stitching function");
       goto err2;
     }
     bounds[i] = obj2.getNum();
@@ -654,12 +655,12 @@ StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict, std::set<int>
   //----- Encode
   if (!dict->lookup("Encode", &obj1)->isArray() ||
       obj1.arrayGetLength() != 2 * k) {
-    error(-1, "Missing or invalid 'Encode' entry in stitching function");
+    error(errSyntaxError, -1, "Missing or invalid 'Encode' entry in stitching function");
     goto err1;
   }
   for (i = 0; i < 2 * k; ++i) {
     if (!obj1.arrayGet(i, &obj2)->isNum()) {
-      error(-1, "Invalid type in 'Encode' array in stitching function");
+      error(errSyntaxError, -1, "Invalid type in 'Encode' array in stitching function");
       goto err2;
     }
     encode[i] = obj2.getNum();
@@ -969,7 +970,7 @@ private:
   GBool checkOverflow(int n = 1)
   {
     if (sp - n < 0) {
-      error(-1, "Stack overflow in PostScript function");
+      error(errSyntaxError, -1, "Stack overflow in PostScript function");
       return gFalse;
     }
     return gTrue;
@@ -977,7 +978,7 @@ private:
   GBool checkUnderflow()
   {
     if (sp == psStackSize) {
-      error(-1, "Stack underflow in PostScript function");
+      error(errSyntaxError, -1, "Stack underflow in PostScript function");
       return gFalse;
     }
     return gTrue;
@@ -985,7 +986,7 @@ private:
   GBool checkType(PSObjectType t1, PSObjectType t2)
   {
     if (stack[sp].type != t1 && stack[sp].type != t2) {
-      error(-1, "Type mismatch in PostScript function");
+      error(errSyntaxError, -1, "Type mismatch in PostScript function");
       return gFalse;
     }
     return gTrue;
@@ -999,7 +1000,7 @@ void PSStack::copy(int n) {
   int i;
 
   if (sp + n > psStackSize) {
-    error(-1, "Stack underflow in PostScript function");
+    error(errSyntaxError, -1, "Stack underflow in PostScript function");
     return;
   }
   if (!checkOverflow(n)) {
@@ -1064,13 +1065,13 @@ PostScriptFunction::PostScriptFunction(Object *funcObj, Dict *dict) {
     goto err1;
   }
   if (!hasRange) {
-    error(-1, "Type 4 function is missing range");
+    error(errSyntaxError, -1, "Type 4 function is missing range");
     goto err1;
   }
 
   //----- get the stream
   if (!funcObj->isStream()) {
-    error(-1, "Type 4 function isn't a stream");
+    error(errSyntaxError, -1, "Type 4 function isn't a stream");
     goto err1;
   }
   str = funcObj->getStream();
@@ -1079,7 +1080,7 @@ PostScriptFunction::PostScriptFunction(Object *funcObj, Dict *dict) {
   codeString = new GooString();
   str->reset();
   if (!(tok = getToken(str)) || tok->cmp("{")) {
-    error(-1, "Expected '{' at start of PostScript function");
+    error(errSyntaxError, -1, "Expected '{' at start of PostScript function");
     if (tok) {
       delete tok;
     }
@@ -1145,7 +1146,7 @@ GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) {
 
   while (1) {
     if (!(tok = getToken(str))) {
-      error(-1, "Unexpected end of PostScript function stream");
+      error(errSyntaxError, -1, "Unexpected end of PostScript function stream");
       return gFalse;
     }
     p = tok->getCString();
@@ -1176,7 +1177,7 @@ GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) {
 	return gFalse;
       }
       if (!(tok = getToken(str))) {
-	error(-1, "Unexpected end of PostScript function stream");
+	error(errSyntaxError, -1, "Unexpected end of PostScript function stream");
 	return gFalse;
       }
       if (!tok->cmp("{")) {
@@ -1186,7 +1187,7 @@ GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) {
 	}
 	delete tok;
 	if (!(tok = getToken(str))) {
-	  error(-1, "Unexpected end of PostScript function stream");
+	  error(errSyntaxError, -1, "Unexpected end of PostScript function stream");
 	  return gFalse;
 	}
       } else {
@@ -1194,7 +1195,8 @@ GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) {
       }
       if (!tok->cmp("if")) {
 	if (elsePtr >= 0) {
-	  error(-1, "Got 'if' operator with two blocks in PostScript function");
+	  error(errSyntaxError, -1,
+		"Got 'if' operator with two blocks in PostScript function");
 	  return gFalse;
 	}
 	code[opPtr].type = psOperator;
@@ -1203,7 +1205,8 @@ GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) {
 	code[opPtr+2].blk = *codePtr;
       } else if (!tok->cmp("ifelse")) {
 	if (elsePtr < 0) {
-	  error(-1, "Got 'ifelse' operator with one blocks in PostScript function");
+	  error(errSyntaxError, -1,
+		"Got 'ifelse' operator with one block in PostScript function");
 	  return gFalse;
 	}
 	code[opPtr].type = psOperator;
@@ -1213,7 +1216,8 @@ GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) {
 	code[opPtr+2].type = psBlock;
 	code[opPtr+2].blk = *codePtr;
       } else {
-	error(-1, "Expected if/ifelse operator in PostScript function");
+	error(errSyntaxError, -1,
+	      "Expected if/ifelse operator in PostScript function");
 	delete tok;
 	return gFalse;
       }
@@ -1241,8 +1245,9 @@ GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) {
 	}
       }
       if (cmp != 0) {
-	error(-1, "Unknown operator '%s' in PostScript function",
-	      tok->getCString());
+	error(errSyntaxError, -1,
+	      "Unknown operator '{0:t}' in PostScript function",
+	      tok);
 	delete tok;
 	return gFalse;
       }
@@ -1620,7 +1625,7 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) {
       }
       break;
     default:
-      error(-1, "Internal: bad object in PostScript function code");
+      error(errSyntaxError, -1, "Internal: bad object in PostScript function code");
       break;
     }
   }
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index c791fb4..23fe930 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -392,7 +392,7 @@ GfxFont *GfxResources::lookupFont(char *name) {
 	return font;
     }
   }
-  error(-1, "Unknown font tag '%s'", name);
+  error(errSyntaxError, -1, "Unknown font tag '{0:s}'", name);
   return NULL;
 }
 
@@ -406,7 +406,7 @@ GBool GfxResources::lookupXObject(char *name, Object *obj) {
       obj->free();
     }
   }
-  error(-1, "XObject '%s' is unknown", name);
+  error(errSyntaxError, -1, "XObject '{0:s}' is unknown", name);
   return gFalse;
 }
 
@@ -420,7 +420,7 @@ GBool GfxResources::lookupXObjectNF(char *name, Object *obj) {
       obj->free();
     }
   }
-  error(-1, "XObject '%s' is unknown", name);
+  error(errSyntaxError, -1, "XObject '{0:s}' is unknown", name);
   return gFalse;
 }
 
@@ -434,7 +434,7 @@ GBool GfxResources::lookupMarkedContentNF(char *name, Object *obj) {
       obj->free();
     }
   }
-  error(-1, "Marked Content '%s' is unknown", name);
+  error(errSyntaxError, -1, "Marked Content '{0:s}' is unknown", name);
   return gFalse;
 }
 
@@ -467,7 +467,7 @@ GfxPattern *GfxResources::lookupPattern(char *name, Gfx *gfx) {
       obj.free();
     }
   }
-  error(-1, "Unknown pattern '%s'", name);
+  error(errSyntaxError, -1, "Unknown pattern '{0:s}'", name);
   return NULL;
 }
 
@@ -486,7 +486,7 @@ GfxShading *GfxResources::lookupShading(char *name, Gfx *gfx) {
       obj.free();
     }
   }
-  error(-1, "Unknown shading '%s'", name);
+  error(errSyntaxError, -1, "ExtGState '{0:s}' is unknown", name);
   return NULL;
 }
 
@@ -517,7 +517,7 @@ GBool GfxResources::lookupGStateNF(char *name, Object *obj) {
       obj->free();
     }
   }
-  error(-1, "ExtGState '%s' is unknown", name);
+  error(errSyntaxError, -1, "ExtGState '{0:s}' is unknown", name);
   return gFalse;
 }
 
@@ -639,7 +639,7 @@ Gfx::~Gfx() {
   }
   // There shouldn't be more saves, but pop them if there were any
   while (state->hasSaves()) {
-    error(-1, "Found state under last state guard. Popping.");
+    error(errSyntaxError, -1, "Found state under last state guard. Popping.");
     restoreState();
   }
   if (!subPage) {
@@ -664,14 +664,14 @@ void Gfx::display(Object *obj, GBool topLevel) {
     for (i = 0; i < obj->arrayGetLength(); ++i) {
       obj->arrayGet(i, &obj2);
       if (!obj2.isStream()) {
-	error(-1, "Weird page contents");
+	error(errSyntaxError, -1, "Weird page contents");
 	obj2.free();
 	return;
       }
       obj2.free();
     }
   } else if (!obj->isStream()) {
-    error(-1, "Weird page contents");
+    error(errSyntaxError, -1, "Weird page contents");
     return;
   }
   parser = new Parser(xref, new Lexer(xref, obj), gFalse);
@@ -764,7 +764,7 @@ void Gfx::go(GBool topLevel) {
 
     // too many arguments - something is wrong
     } else {
-      error(getPos(), "Too many args in content stream");
+      error(errSyntaxError, getPos(), "Too many args in content stream");
       if (printCommands) {
 	printf("throwing away arg: ");
 	obj.print(stdout);
@@ -781,7 +781,7 @@ void Gfx::go(GBool topLevel) {
 
   // args at end with no command
   if (numArgs > 0) {
-    error(getPos(), "Leftover args in content stream");
+    error(errSyntaxError, getPos(), "Leftover args in content stream");
     if (printCommands) {
       printf("%d leftovers:", numArgs);
       for (i = 0; i < numArgs; ++i) {
@@ -813,7 +813,7 @@ void Gfx::execOp(Object *cmd, Object args[], int numArgs) {
   name = cmd->getCmd();
   if (!(op = findOp(name))) {
     if (ignoreUndef == 0)
-      error(getPos(), "Unknown operator '%s'", name);
+      error(errSyntaxError, getPos(), "Unknown operator '{0:s}'", name);
     return;
   }
 
@@ -821,27 +821,28 @@ void Gfx::execOp(Object *cmd, Object args[], int numArgs) {
   argPtr = args;
   if (op->numArgs >= 0) {
     if (numArgs < op->numArgs) {
-      error(getPos(), "Too few (%d) args to '%s' operator", numArgs, name);
+      error(errSyntaxError, getPos(), "Too few ({0:d}) args to '{1:s}' operator", numArgs, name);
       commandAborted = gTrue;
       return;
     }
     if (numArgs > op->numArgs) {
 #if 0
-      error(getPos(), "Too many (%d) args to '%s' operator", numArgs, name);
+      error(errSyntaxWarning, getPos(),
+	    "Too many ({0:d}) args to '{1:s}' operator", numArgs, name);
 #endif
       argPtr += numArgs - op->numArgs;
       numArgs = op->numArgs;
     }
   } else {
     if (numArgs > -op->numArgs) {
-      error(getPos(), "Too many (%d) args to '%s' operator",
+      error(errSyntaxError, getPos(), "Too many ({0:d}) args to '{1:s}' operator",
 	    numArgs, name);
       return;
     }
   }
   for (i = 0; i < numArgs; ++i) {
     if (!checkArg(&argPtr[i], op->tchk[i])) {
-      error(getPos(), "Arg #%d to '%s' operator is wrong type (%s)",
+      error(errSyntaxError, getPos(), "Arg #{0:d} to '{1:s}' operator is wrong type ({2:s})",
 	    i, name, argPtr[i].getTypeName());
       return;
     }
@@ -975,7 +976,7 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
     return;
   }
   if (!obj1.isDict()) {
-    error(getPos(), "ExtGState '%s' is wrong type", args[0].getName());
+    error(errSyntaxError, getPos(), "ExtGState '{0:s}' is wrong type", args[0].getName());
     obj1.free();
     return;
   }
@@ -991,7 +992,7 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
       state->setBlendMode(mode);
       out->updateBlendMode(state);
     } else {
-      error(getPos(), "Invalid blend mode in ExtGState");
+      error(errSyntaxError, getPos(), "Invalid blend mode in ExtGState");
     }
   }
   obj2.free();
@@ -1064,7 +1065,7 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
       out->updateTransfer(state);
     }
   } else if (!obj2.isNull()) {
-    error(getPos(), "Invalid transfer function in ExtGState");
+    error(errSyntaxError, getPos(), "Invalid transfer function in ExtGState");
   }
   obj2.free();
 
@@ -1098,7 +1099,7 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
 	funcs[0] = Function::parse(&obj3);
 	if (funcs[0]->getInputSize() != 1 ||
 	    funcs[0]->getOutputSize() != 1) {
-	  error(getPos(),
+	  error(errSyntaxError, getPos(),
 		"Invalid transfer function in soft mask in ExtGState");
 	  delete funcs[0];
 	  funcs[0] = NULL;
@@ -1150,15 +1151,15 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
 	    delete funcs[0];
 	  }
 	} else {
-	  error(getPos(), "Invalid soft mask in ExtGState - missing group");
+	  error(errSyntaxError, getPos(), "Invalid soft mask in ExtGState - missing group");
 	}
 	obj4.free();
       } else {
-	error(getPos(), "Invalid soft mask in ExtGState - missing group");
+	error(errSyntaxError, getPos(), "Invalid soft mask in ExtGState - missing group");
       }
       obj3.free();
     } else if (!obj2.isNull()) {
-      error(getPos(), "Invalid soft mask in ExtGState");
+      error(errSyntaxError, getPos(), "Invalid soft mask in ExtGState");
     }
   }
   obj2.free();
@@ -1185,7 +1186,7 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
       fargs0.free();
       fargs1.free();
     } else {
-      error(getPos(), "Number of args mismatch for /Font in ExtGState");
+      error(errSyntaxError, getPos(), "Number of args mismatch for /Font in ExtGState");
     }
   }
   obj2.free();
@@ -1217,7 +1218,7 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
       dargs[0].free();
       dargs[1].free();
     } else {
-      error(getPos(), "Number of args mismatch for /D in ExtGState");
+      error(errSyntaxError, getPos(), "Number of args mismatch for /D in ExtGState");
     }
   }
   obj2.free();
@@ -1253,7 +1254,7 @@ void Gfx::doSoftMask(Object *str, GBool alpha,
   // check form type
   dict->lookup("FormType", &obj1);
   if (!(obj1.isNull() || (obj1.isInt() && obj1.getInt() == 1))) {
-    error(getPos(), "Unknown form type");
+    error(errSyntaxError, getPos(), "Unknown form type");
   }
   obj1.free();
 
@@ -1261,7 +1262,7 @@ void Gfx::doSoftMask(Object *str, GBool alpha,
   dict->lookup("BBox", &obj1);
   if (!obj1.isArray()) {
     obj1.free();
-    error(getPos(), "Bad form bounding box");
+    error(errSyntaxError, getPos(), "Bad form bounding box");
     return;
   }
   for (i = 0; i < 4; ++i) {
@@ -1270,7 +1271,7 @@ void Gfx::doSoftMask(Object *str, GBool alpha,
     else {
       obj2.free();
       obj1.free();
-      error(getPos(), "Bad form bounding box (non number)");
+      error(errSyntaxError, getPos(), "Bad form bounding box (non number)");
       return;
     }
     obj2.free();
@@ -1532,7 +1533,7 @@ void Gfx::opSetFillColorSpace(Object args[], int numArgs) {
       textHaveCSPattern = gTrue;
     }
   } else {
-    error(getPos(), "Bad color space (fill)");
+    error(errSyntaxError, getPos(), "Bad color space (fill)");
   }
 }
 
@@ -1556,7 +1557,7 @@ void Gfx::opSetStrokeColorSpace(Object args[], int numArgs) {
     state->setStrokeColor(&color);
     out->updateStrokeColor(state);
   } else {
-    error(getPos(), "Bad color space (stroke)");
+    error(errSyntaxError, getPos(), "Bad color space (stroke)");
   }
 }
 
@@ -1565,7 +1566,7 @@ void Gfx::opSetFillColor(Object args[], int numArgs) {
   int i;
 
   if (numArgs != state->getFillColorSpace()->getNComps()) {
-    error(getPos(), "Incorrect number of arguments in 'sc' command");
+    error(errSyntaxError, getPos(), "Incorrect number of arguments in 'sc' command");
     return;
   }
   state->setFillPattern(NULL);
@@ -1581,7 +1582,7 @@ void Gfx::opSetStrokeColor(Object args[], int numArgs) {
   int i;
 
   if (numArgs != state->getStrokeColorSpace()->getNComps()) {
-    error(getPos(), "Incorrect number of arguments in 'SC' command");
+    error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SC' command");
     return;
   }
   state->setStrokePattern(NULL);
@@ -1602,7 +1603,7 @@ void Gfx::opSetFillColorN(Object args[], int numArgs) {
       if (!((GfxPatternColorSpace *)state->getFillColorSpace())->getUnder() ||
 	  numArgs - 1 != ((GfxPatternColorSpace *)state->getFillColorSpace())
 	                     ->getUnder()->getNComps()) {
-	error(getPos(), "Incorrect number of arguments in 'scn' command");
+	error(errSyntaxError, getPos(), "Incorrect number of arguments in 'scn' command");
 	return;
       }
       for (i = 0; i < numArgs - 1 && i < gfxColorMaxComps; ++i) {
@@ -1622,7 +1623,7 @@ void Gfx::opSetFillColorN(Object args[], int numArgs) {
 
   } else {
     if (numArgs != state->getFillColorSpace()->getNComps()) {
-      error(getPos(), "Incorrect number of arguments in 'scn' command");
+      error(errSyntaxError, getPos(), "Incorrect number of arguments in 'scn' command");
       return;
     }
     state->setFillPattern(NULL);
@@ -1649,7 +1650,7 @@ void Gfx::opSetStrokeColorN(Object args[], int numArgs) {
 	       ->getUnder() ||
 	  numArgs - 1 != ((GfxPatternColorSpace *)state->getStrokeColorSpace())
 	                     ->getUnder()->getNComps()) {
-	error(getPos(), "Incorrect number of arguments in 'SCN' command");
+	error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SCN' command");
 	return;
       }
       for (i = 0; i < numArgs - 1 && i < gfxColorMaxComps; ++i) {
@@ -1669,7 +1670,7 @@ void Gfx::opSetStrokeColorN(Object args[], int numArgs) {
 
   } else {
     if (numArgs != state->getStrokeColorSpace()->getNComps()) {
-      error(getPos(), "Incorrect number of arguments in 'SCN' command");
+      error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SCN' command");
       return;
     }
     state->setStrokePattern(NULL);
@@ -1695,7 +1696,7 @@ void Gfx::opMoveTo(Object args[], int numArgs) {
 
 void Gfx::opLineTo(Object args[], int numArgs) {
   if (!state->isCurPt()) {
-    error(getPos(), "No current point in lineto");
+    error(errSyntaxError, getPos(), "No current point in lineto");
     return;
   }
   state->lineTo(args[0].getNum(), args[1].getNum());
@@ -1705,7 +1706,7 @@ void Gfx::opCurveTo(Object args[], int numArgs) {
   double x1, y1, x2, y2, x3, y3;
 
   if (!state->isCurPt()) {
-    error(getPos(), "No current point in curveto");
+    error(errSyntaxError, getPos(), "No current point in curveto");
     return;
   }
   x1 = args[0].getNum();
@@ -1721,7 +1722,7 @@ void Gfx::opCurveTo1(Object args[], int numArgs) {
   double x1, y1, x2, y2, x3, y3;
 
   if (!state->isCurPt()) {
-    error(getPos(), "No current point in curveto1");
+    error(errSyntaxError, getPos(), "No current point in curveto1");
     return;
   }
   x1 = state->getCurX();
@@ -1737,7 +1738,7 @@ void Gfx::opCurveTo2(Object args[], int numArgs) {
   double x1, y1, x2, y2, x3, y3;
 
   if (!state->isCurPt()) {
-    error(getPos(), "No current point in curveto2");
+    error(errSyntaxError, getPos(), "No current point in curveto2");
     return;
   }
   x1 = args[0].getNum();
@@ -1765,7 +1766,7 @@ void Gfx::opRectangle(Object args[], int numArgs) {
 
 void Gfx::opClosePath(Object args[], int numArgs) {
   if (!state->isCurPt()) {
-    error(getPos(), "No current point in closepath");
+    error(errSyntaxError, getPos(), "No current point in closepath");
     return;
   }
   state->closePath();
@@ -1781,7 +1782,7 @@ void Gfx::opEndPath(Object args[], int numArgs) {
 
 void Gfx::opStroke(Object args[], int numArgs) {
   if (!state->isCurPt()) {
-    //error(getPos(), "No path in stroke");
+    //error(errSyntaxError, getPos(), "No path in stroke");
     return;
   }
   if (state->isPath() && !contentIsHidden()) {
@@ -1796,7 +1797,7 @@ void Gfx::opStroke(Object args[], int numArgs) {
 
 void Gfx::opCloseStroke(Object * /*args[]*/, int /*numArgs*/) {
   if (!state->isCurPt()) {
-    //error(getPos(), "No path in closepath/stroke");
+    //error(errSyntaxError, getPos(), "No path in closepath/stroke");
     return;
   }
   state->closePath();
@@ -1812,7 +1813,7 @@ void Gfx::opCloseStroke(Object * /*args[]*/, int /*numArgs*/) {
 
 void Gfx::opFill(Object args[], int numArgs) {
   if (!state->isCurPt()) {
-    //error(getPos(), "No path in fill");
+    //error(errSyntaxError, getPos(), "No path in fill");
     return;
   }
   if (state->isPath() && !contentIsHidden()) {
@@ -1827,7 +1828,7 @@ void Gfx::opFill(Object args[], int numArgs) {
 
 void Gfx::opEOFill(Object args[], int numArgs) {
   if (!state->isCurPt()) {
-    //error(getPos(), "No path in eofill");
+    //error(errSyntaxError, getPos(), "No path in eofill");
     return;
   }
   if (state->isPath() && !contentIsHidden()) {
@@ -1842,7 +1843,7 @@ void Gfx::opEOFill(Object args[], int numArgs) {
 
 void Gfx::opFillStroke(Object args[], int numArgs) {
   if (!state->isCurPt()) {
-    //error(getPos(), "No path in fill/stroke");
+    //error(errSyntaxError, getPos(), "No path in fill/stroke");
     return;
   }
   if (state->isPath() && !contentIsHidden()) {
@@ -1862,7 +1863,7 @@ void Gfx::opFillStroke(Object args[], int numArgs) {
 
 void Gfx::opCloseFillStroke(Object args[], int numArgs) {
   if (!state->isCurPt()) {
-    //error(getPos(), "No path in closepath/fill/stroke");
+    //error(errSyntaxError, getPos(), "No path in closepath/fill/stroke");
     return;
   }
   if (state->isPath() && !contentIsHidden()) {
@@ -1883,7 +1884,7 @@ void Gfx::opCloseFillStroke(Object args[], int numArgs) {
 
 void Gfx::opEOFillStroke(Object args[], int numArgs) {
   if (!state->isCurPt()) {
-    //error(getPos(), "No path in eofill/stroke");
+    //error(errSyntaxError, getPos(), "No path in eofill/stroke");
     return;
   }
   if (state->isPath() && !contentIsHidden()) {
@@ -1903,7 +1904,7 @@ void Gfx::opEOFillStroke(Object args[], int numArgs) {
 
 void Gfx::opCloseEOFillStroke(Object args[], int numArgs) {
   if (!state->isCurPt()) {
-    //error(getPos(), "No path in closepath/eofill/stroke");
+    //error(errSyntaxError, getPos(), "No path in closepath/eofill/stroke");
     return;
   }
   if (state->isPath() && !contentIsHidden()) {
@@ -1943,7 +1944,7 @@ void Gfx::doPatternFill(GBool eoFill) {
     doShadingPatternFill((GfxShadingPattern *)pattern, gFalse, eoFill);
     break;
   default:
-    error(getPos(), "Unimplemented pattern type (%d) in fill",
+    error(errSyntaxError, getPos(), "Unimplemented pattern type ({0:d}) in fill",
 	  pattern->getType());
     break;
   }
@@ -1970,7 +1971,7 @@ void Gfx::doPatternStroke() {
     doShadingPatternFill((GfxShadingPattern *)pattern, gTrue, gFalse);
     break;
   default:
-    error(getPos(), "Unimplemented pattern type (%d) in stroke",
+    error(errSyntaxError, getPos(), "Unimplemented pattern type ({0:d}) in stroke",
 	  pattern->getType());
     break;
   }
@@ -3690,7 +3691,7 @@ void Gfx::opTextNextLine(Object args[], int numArgs) {
 
 void Gfx::opShowText(Object args[], int numArgs) {
   if (!state->getFont()) {
-    error(getPos(), "No font in show");
+    error(errSyntaxError, getPos(), "No font in show");
     return;
   }
   if (fontChanged) {
@@ -3706,7 +3707,7 @@ void Gfx::opMoveShowText(Object args[], int numArgs) {
   double tx, ty;
 
   if (!state->getFont()) {
-    error(getPos(), "No font in move/show");
+    error(errSyntaxError, getPos(), "No font in move/show");
     return;
   }
   if (fontChanged) {
@@ -3726,7 +3727,7 @@ void Gfx::opMoveSetShowText(Object args[], int numArgs) {
   double tx, ty;
 
   if (!state->getFont()) {
-    error(getPos(), "No font in move/set/show");
+    error(errSyntaxError, getPos(), "No font in move/set/show");
     return;
   }
   if (fontChanged) {
@@ -3753,7 +3754,7 @@ void Gfx::opShowSpaceText(Object args[], int numArgs) {
   int i;
 
   if (!state->getFont()) {
-    error(getPos(), "No font in show/space");
+    error(errSyntaxError, getPos(), "No font in show/space");
     return;
   }
   if (fontChanged) {
@@ -3779,7 +3780,7 @@ void Gfx::opShowSpaceText(Object args[], int numArgs) {
     } else if (obj.isString()) {
       doShowText(obj.getString());
     } else {
-      error(getPos(), "Element of show/space array must be number or string");
+      error(errSyntaxError, getPos(), "Element of show/space array must be number or string");
     }
     obj.free();
   }
@@ -3864,7 +3865,7 @@ void Gfx::doShowText(GooString *s) {
 	if (charProc.isStream()) {
 	  display(&charProc, gFalse);
 	} else {
-	  error(getPos(), "Missing or bad Type3 CharProc entry");
+	  error(errSyntaxError, getPos(), "Missing or bad Type3 CharProc entry");
 	}
 	out->endType3Char(state);
 	if (resDict) {
@@ -3978,7 +3979,7 @@ void Gfx::opXObject(Object args[], int numArgs) {
     return;
   }
   if (!obj1.isStream()) {
-    error(getPos(), "XObject '%s' is wrong type", name);
+      error(errSyntaxError, getPos(), "XObject '{0:s}' is wrong type", name);
     obj1.free();
     return;
   }
@@ -3993,7 +3994,7 @@ void Gfx::opXObject(Object args[], int numArgs) {
       return;
     }
   } else {
-    error(getPos(), "XObject OC value not null or dict: %i", obj2.getType());
+    error(errSyntaxError, getPos(), "XObject OC value not null or dict: {0:d}", obj2.getType());
   }
   obj2.free();
 
@@ -4023,9 +4024,9 @@ void Gfx::opXObject(Object args[], int numArgs) {
     out->psXObject(obj1.getStream(),
 		   obj3.isStream() ? obj3.getStream() : (Stream *)NULL);
   } else if (obj2.isName()) {
-    error(getPos(), "Unknown XObject subtype '%s'", obj2.getName());
+    error(errSyntaxError, getPos(), "Unknown XObject subtype '{0:s}'", obj2.getName());
   } else {
-    error(getPos(), "XObject subtype is missing or wrong type");
+    error(errSyntaxError, getPos(), "XObject subtype is missing or wrong type");
   }
   obj2.free();
 #if OPI_SUPPORT
@@ -4332,10 +4333,10 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
 	if (obj1.isInt()) {
 	  maskColors[i] = obj1.getInt();
 	} else if (obj1.isReal()) {
-	  error(-1, "Mask entry should be an integer but it's a real, trying to use it");
+	  error(errSyntaxError, -1, "Mask entry should be an integer but it's a real, trying to use it");
 	  maskColors[i] = (int) obj1.getReal();
 	} else {
-	  error(-1, "Mask entry should be an integer but it's of type %d", obj1.getType());
+	  error(errSyntaxError, -1, "Mask entry should be an integer but it's of type {0:d}", obj1.getType());
 	  obj1.free();
 	  goto err1;
 	}
@@ -4439,7 +4440,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
  err2:
   obj1.free();
  err1:
-  error(getPos(), "Bad image parameters");
+  error(errSyntaxError, getPos(), "Bad image parameters");
 }
 
 void Gfx::doForm(Object *str) {
@@ -4464,7 +4465,7 @@ void Gfx::doForm(Object *str) {
   // check form type
   dict->lookup("FormType", &obj1);
   if (!(obj1.isNull() || (obj1.isInt() && obj1.getInt() == 1))) {
-    error(getPos(), "Unknown form type");
+    error(errSyntaxError, getPos(), "Unknown form type");
   }
   obj1.free();
 
@@ -4472,7 +4473,7 @@ void Gfx::doForm(Object *str) {
   dict->lookup("BBox", &bboxObj);
   if (!bboxObj.isArray()) {
     bboxObj.free();
-    error(getPos(), "Bad form bounding box");
+    error(errSyntaxError, getPos(), "Bad form bounding box");
     return;
   }
   for (i = 0; i < 4; ++i) {
@@ -4482,7 +4483,7 @@ void Gfx::doForm(Object *str) {
       obj1.free();
     } else {
       obj1.free();
-      error(getPos(), "Bad form bounding box value");
+      error(errSyntaxError, getPos(), "Bad form bounding box value");
       return;
     }
   }
@@ -4612,12 +4613,12 @@ void Gfx::doForm1(Object *str, Dict *resDict, double *matrix, double *bbox,
   
   if (stateBefore != state) {
     if (state->isParentState(stateBefore)) {
-      error(-1, "There's a form with more q than Q, trying to fix");
+      error(errSyntaxError, -1, "There's a form with more q than Q, trying to fix");
       while (stateBefore != state) {
         restoreState();
       }
     } else {
-      error(-1, "There's a form with more Q than q");
+      error(errSyntaxError, -1, "There's a form with more Q than q");
     }
   }
 
@@ -4685,7 +4686,7 @@ Stream *Gfx::buildImageStream() {
   parser->getObj(&obj);
   while (!obj.isCmd("ID") && !obj.isEOF()) {
     if (!obj.isName()) {
-      error(getPos(), "Inline image dictionary key must be a name object");
+      error(errSyntaxError, getPos(), "Inline image dictionary key must be a name object");
       obj.free();
     } else {
       key = copyString(obj.getName());
@@ -4700,7 +4701,7 @@ Stream *Gfx::buildImageStream() {
     parser->getObj(&obj);
   }
   if (obj.isEOF()) {
-    error(getPos(), "End of file in inline image");
+    error(errSyntaxError, getPos(), "End of file in inline image");
     obj.free();
     dict.free();
     return NULL;
@@ -4720,11 +4721,11 @@ Stream *Gfx::buildImageStream() {
 }
 
 void Gfx::opImageData(Object args[], int numArgs) {
-  error(getPos(), "Internal: got 'ID' operator");
+  error(errInternal, getPos(), "Got 'ID' operator");
 }
 
 void Gfx::opEndImage(Object args[], int numArgs) {
-  error(getPos(), "Internal: got 'EI' operator");
+  error(errInternal, getPos(), "Got 'EI' operator");
 }
 
 //------------------------------------------------------------------------
@@ -4795,7 +4796,7 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) {
   if ( strncmp( name0, "OC", 2) == 0 && contentConfig) {
     if ( numArgs >= 2 ) {
       if (!args[1].isName()) {
-	error(getPos(), "Unexpected MC Type: %i", args[1].getType());
+	error(errSyntaxError, getPos(), "Unexpected MC Type: {0:d}", args[1].getType());
       }
       char* name1 = args[1].getName();
       Object markedContent;
@@ -4806,10 +4807,10 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) {
 	  mc->ocSuppressed = !(visible);
        }
       } else {
-	error(getPos(), "DID NOT find %s", name1);
+	error(errSyntaxError, getPos(), "DID NOT find {0:s}", name1);
       }
     } else {
-      error(getPos(), "insufficient arguments for Marked Content");
+      error(errSyntaxError, getPos(), "insufficient arguments for Marked Content");
     }
   }
 
@@ -4910,7 +4911,7 @@ void Gfx::drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor,
     dict->lookup("BBox", &bboxObj);
     if (!bboxObj.isArray()) {
       bboxObj.free();
-      error(getPos(), "Bad form bounding box");
+      error(errSyntaxError, getPos(), "Bad form bounding box");
       return;
     }
     for (i = 0; i < 4; ++i) {
@@ -4920,7 +4921,7 @@ void Gfx::drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor,
         obj1.free();
       } else {
         obj1.free();
-        error(getPos(), "Bad form bounding box value");
+        error(errSyntaxError, getPos(), "Bad form bounding box value");
         return;
       }
     }
@@ -5057,7 +5058,7 @@ void Gfx::saveState() {
 
 void Gfx::restoreState() {
   if (stackHeight <= bottomGuard() || !state->hasSaves()) {
-    error(-1, "Restoring state when no valid states to pop");
+    error(errSyntaxError, -1, "Restoring state when no valid states to pop");
     commandAborted = gTrue;
     return;
   }
diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc
index f4ff78c..20b68cb 100644
--- a/poppler/GfxFont.cc
+++ b/poppler/GfxFont.cc
@@ -159,7 +159,7 @@ GfxFont *GfxFont::makeFont(XRef *xref, const char *tagA, Ref idA, Dict *fontDict
   } else if (obj1.isName("Type0")) {
     font = new GfxCIDFont(xref, tagA, idA, nameA, fontDict);
   } else {
-    error(-1, "Unknown font type: '%s'",
+    error(errSyntaxError, -1, "Unknown font type: '{0:s}'",
 	  obj1.isName() ? obj1.getName() : "???");
     font = new Gfx8BitFont(xref, tagA, idA, nameA, fontUnknownType, fontDict);
   }
@@ -242,7 +242,7 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
       obj1.dictLookup("Fontname", &obj2);
       if (obj2.isName()) {
         embFontName = new GooString(obj2.getName());
-        error(-1, "The file uses Fontname instead of FontName please notify the creator that the file is broken");
+        error(errSyntaxWarning, -1, "The file uses Fontname instead of FontName please notify the creator that the file is broken");
       }
       obj2.free();
     }
@@ -264,7 +264,7 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
       else if (strcmp(obj2.getName(), "Expanded") == 0) stretch = Expanded;
       else if (strcmp(obj2.getName(), "ExtraExpanded") == 0) stretch = ExtraExpanded;
       else if (strcmp(obj2.getName(), "UltraExpanded") == 0) stretch = UltraExpanded;
-      else error(-1, "Invalid Font Stretch");
+      else error(errSyntaxWarning, -1, "Invalid Font Stretch");
     }
     obj2.free();
     
@@ -280,7 +280,7 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
       else if (obj2.getNum() == 700) weight = W700;
       else if (obj2.getNum() == 800) weight = W800;
       else if (obj2.getNum() == 900) weight = W900;
-      else error(-1, "Invalid Font Weight");
+      else error(errSyntaxWarning, -1, "Invalid Font Weight");
     }
     obj2.free();
 
@@ -288,9 +288,9 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
     if (obj1.dictLookupNF("FontFile", &obj2)->isRef()) {
       embFontID = obj2.getRef();
       if (type != fontType1) {
-	error(-1, "Mismatch between font type and embedded font file");
+	error(errSyntaxError, -1, "Mismatch between font type and embedded font file");
 	if (isCIDFont()) {
-	  error(-1, "CID font has FontFile attribute; assuming CIDType0");
+	  error(errSyntaxError, -1, "CID font has FontFile attribute; assuming CIDType0");
 	  type = fontCIDType0;
 	} else {
 	  type = fontType1;
@@ -302,7 +302,7 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
 	obj1.dictLookupNF("FontFile2", &obj2)->isRef()) {
       embFontID = obj2.getRef();
       if (type != fontTrueType && type != fontCIDType2) {
-	error(-1, "Mismatch between font type and embedded font file");
+	error(errSyntaxError, -1, "Mismatch between font type and embedded font file");
 	type = isCIDFont() ? fontCIDType2 : fontTrueType;
       }
     }
@@ -314,9 +314,9 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
 	if (obj4.isName("Type1")) {
 	  embFontID = obj2.getRef();
 	  if (type != fontType1) {
-	    error(-1, "Mismatch between font type and embedded font file");
+	    error(errSyntaxError, -1, "Mismatch between font type and embedded font file");
 	    if (isCIDFont()) {
-	      error(-1, "Embedded CID font has type Type1; assuming CIDType0");
+	      error(errSyntaxError, -1, "Embedded CID font has type Type1; assuming CIDType0");
 	      type = fontCIDType0;
 	    } else {
 	      type = fontType1;
@@ -325,10 +325,10 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
 	} else if (obj4.isName("Type1C")) {
 	  embFontID = obj2.getRef();
 	  if (type != fontType1 && type != fontType1C) {
-	    error(-1, "Mismatch between font type and embedded font file");
+	    error(errSyntaxError, -1, "Mismatch between font type and embedded font file");
 	  }
 	  if (isCIDFont()) {
-	    error(-1, "Embedded CID font has type Type1C; assuming CIDType0C");
+	    error(errSyntaxError, -1, "Embedded CID font has type Type1C; assuming CIDType0C");
 	    type = fontCIDType0C;
 	  } else {
 	    type = fontType1C;
@@ -336,9 +336,9 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
 	} else if (obj4.isName("TrueType")) {
 	  embFontID = obj2.getRef();
 	  if (type != fontTrueType) {
-	    error(-1, "Mismatch between font type and embedded font file");
+	    error(errSyntaxError, -1, "Mismatch between font type and embedded font file");
 	    if (isCIDFont()) {
-	      error(-1, "Embedded CID font has type TrueType; assuming CIDType2");
+	      error(errSyntaxError, -1, "Embedded CID font has type TrueType; assuming CIDType2");
 	      type = fontCIDType2;
 	    } else {
 	      type = fontTrueType;
@@ -347,12 +347,12 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
 	} else if (obj4.isName("CIDFontType0C")) {
 	  embFontID = obj2.getRef();
 	  if (type != fontCIDType0) {
-	    error(-1, "Mismatch between font type and embedded font file");
+	    error(errSyntaxError, -1, "Mismatch between font type and embedded font file");
 	  }
 	  if (isCIDFont()) {
 	    type = fontCIDType0C;
 	  } else {
-	    error(-1, "Embedded non-CID font has type CIDFontType0c; assuming Type1C");
+	    error(errSyntaxError, -1, "Embedded non-CID font has type CIDFontType0c; assuming Type1C");
 	    type = fontType1C;
 	  }
 	} else if (obj4.isName("OpenType")) {
@@ -366,10 +366,10 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
 	  } else if (type == fontCIDType2) {
 	    type = fontCIDType2OT;
 	  } else {
-	    error(-1, "Mismatch between font type and embedded font file");
+	    error(errSyntaxError, -1, "Mismatch between font type and embedded font file");
 	  }
 	} else {
-	  error(-1, "Unknown embedded font type '%s'",
+	  error(errSyntaxError, -1, "Unknown embedded font type '{0:s}'",
 		obj4.isName() ? obj4.getName() : "???");
 	}
 	obj4.free();
@@ -465,24 +465,24 @@ char *GfxFont::readExtFontFile(int *len) {
   char *buf;
 
   if (!(f = fopen(extFontFile->getCString(), "rb"))) {
-    error(-1, "External font file '%s' vanished", extFontFile->getCString());
+    error(errIO, -1, "External font file '{0:t}' vanished", extFontFile);
     return NULL;
   }
   if (fseek(f, 0, SEEK_END) != 0) {
-    error(-1, "Cannot seek to end of '%s'", extFontFile->getCString());
+    error(errIO, -1, "Cannot seek to end of '{0:t}'", extFontFile);
     fclose(f);
     return NULL;
   }
   *len = (int)ftell(f);
   if (fseek(f, 0, SEEK_SET) != 0) {
-    error(-1, "Cannot seek to start of '%s'", extFontFile->getCString());
+    error(errIO, -1, "Cannot seek to start of '{0:t}'", extFontFile);
     fclose(f);
     return NULL;
   }
   buf = (char *)gmalloc(*len);
   if ((int)fread(buf, 1, *len, f) != *len) {
-    error(-1, "Error reading external font file '%s'",
-	  extFontFile->getCString());
+    error(errIO, -1, "Error reading external font file '{0:t}'",
+	  extFontFile);
   }
   fclose(f);
   return buf;
@@ -496,7 +496,7 @@ char *GfxFont::readEmbFontFile(XRef *xref, int *len) {
   obj1.initRef(embFontID.num, embFontID.gen);
   obj1.fetch(xref, &obj2);
   if (!obj2.isStream()) {
-    error(-1, "Embedded font file is not a stream");
+    error(errSyntaxError, -1, "Embedded font file is not a stream");
     obj2.free();
     obj1.free();
     embFontID.num = -1;
@@ -642,7 +642,8 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA
     }
     obj1.free();
     if (!fontDict->lookup("CharProcs", &charProcs)->isDict()) {
-      error(-1, "Missing or invalid CharProcs dictionary in Type 3 font");
+      error(errSyntaxError, -1,
+	    "Missing or invalid CharProcs dictionary in Type 3 font");
       charProcs.free();
     }
     if (!fontDict->lookup("Resources", &resources)->isDict()) {
@@ -799,7 +800,8 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA
 	  }
 	  ++code;
 	} else {
-	  error(-1, "Wrong type in font encoding resource differences (%s)",
+	  error(errSyntaxError, -1,
+		"Wrong type in font encoding resource differences ({0:s})",
 		obj3.getTypeName());
 	}
 	obj3.free();
@@ -1020,8 +1022,8 @@ static int parseCharName(char *charName, Unicode *uBuf, int uLen,
 			 GBool numeric, GBool hex, GBool variants)
 {
   if (uLen <= 0) {
-    error(-1, "Zero-length output buffer (recursion overflow?) in "
-	  "parseCharName, component \"%s\"", charName);
+    error(errInternal, -1, "Zero-length output buffer (recursion overflow?) in "
+	  "parseCharName, component \"{0:s}\"", charName);
     return 0;
   }
   // Step 1: drop all the characters from the glyph name starting with the
@@ -1056,7 +1058,7 @@ static int parseCharName(char *charName, Unicode *uBuf, int uLen,
 			       ligaturesRecurse, numeric, hex, variants)))
 	  n += m;
 	else
-	  error(-1, "Could not parse ligature component \"%s\" of \"%s\" in "
+	  error(errSyntaxWarning, -1, "Could not parse ligature component \"{0:s}\" of \"{1:s}\" in "
 		"parseCharName", lig_part, charName);
       }
       lig_part = lig_end + 1;
@@ -1354,12 +1356,12 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
 
   // get the descendant font
   if (!fontDict->lookup("DescendantFonts", &obj1)->isArray()) {
-    error(-1, "Missing DescendantFonts entry in Type 0 font");
+    error(errSyntaxError, -1, "Missing DescendantFonts entry in Type 0 font");
     obj1.free();
     goto err1;
   }
   if (!obj1.arrayGet(0, &desFontDictObj)->isDict()) {
-    error(-1, "Bad descendant font in Type 0 font");
+    error(errSyntaxError, -1, "Bad descendant font in Type 0 font");
     goto err3;
   }
   obj1.free();
@@ -1367,7 +1369,7 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
 
   // font type
   if (!desFontDict->lookup("Subtype", &obj1)) {
-    error(-1, "Missing Subtype entry in Type 0 descendant font");
+    error(errSyntaxError, -1, "Missing Subtype entry in Type 0 descendant font");
     goto err3;
   }
   if (obj1.isName("CIDFontType0")) {
@@ -1375,7 +1377,7 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
   } else if (obj1.isName("CIDFontType2")) {
     type = fontCIDType2;
   } else {
-    error(-1, "Unknown Type 0 descendant font type '%s'",
+    error(errSyntaxError, -1, "Unknown Type 0 descendant font type '{0:s}'",
 	  obj1.isName() ? obj1.getName() : "???");
     goto err3;
   }
@@ -1391,13 +1393,13 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
 
   // char collection
   if (!desFontDict->lookup("CIDSystemInfo", &obj1)->isDict()) {
-    error(-1, "Missing CIDSystemInfo dictionary in Type 0 descendant font");
+    error(errSyntaxError, -1, "Missing CIDSystemInfo dictionary in Type 0 descendant font");
     goto err3;
   }
   obj1.dictLookup("Registry", &obj2);
   obj1.dictLookup("Ordering", &obj3);
   if (!obj2.isString() || !obj3.isString()) {
-    error(-1, "Invalid CIDSystemInfo dictionary in Type 0 descendant font");
+    error(errSyntaxError, -1, "Invalid CIDSystemInfo dictionary in Type 0 descendant font");
     goto err4;
   }
   collection = obj2.getString()->copy()->append('-')->append(obj3.getString());
@@ -1429,13 +1431,13 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
 	};
 	for (size_t i = 0; i < sizeof(knownCollections)/sizeof(knownCollections[0]); i++) {
 	  if (collection->cmp(knownCollections[i]) == 0) {
-	    error(-1, "Missing language pack for '%s' mapping", collection->getCString());
+	    error(errSyntaxError, -1, "Missing language pack for '{0:t}' mapping", collection);
 	    delete collection;
 	    goto err2;
 	  }
 	}
-	error(-1, "Unknown character collection '%s'",
-	      collection->getCString());
+	error(errSyntaxError, -1, "Unknown character collection '{0:t}'",
+	      collection);
 	// fall-through, assuming the Identity mapping -- this appears
 	// to match Adobe's behavior
       }
@@ -1478,7 +1480,7 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
     }
     
     if (!success) {
-      error(-1, "Missing or invalid Encoding entry in Type 0 font");
+      error(errSyntaxError, -1, "Missing or invalid Encoding entry in Type 0 font");
       delete collection;
       goto err3;
     }
@@ -1487,8 +1489,8 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
     cMap = globalParams->getCMap(collection, cMapName);
   }
   if (!cMap) {
-      error(-1, "Unknown CMap '%s' for character collection '%s'",
-	    cMapName->getCString(), collection->getCString());
+      error(errSyntaxError, -1, "Unknown CMap '{0:t}' for character collection '{1:t}'",
+	    cMapName, collection);
       delete collection;
       delete cMapName;
       goto err2;
@@ -1514,7 +1516,7 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
 	cidToGID[cidToGIDLen++] = (Gushort)((c1 << 8) + c2);
       }
     } else if (!obj1.isName("Identity") && !obj1.isNull()) {
-      error(-1, "Invalid CIDToGIDMap entry in CID font");
+      error(errSyntaxError, -1, "Invalid CIDToGIDMap entry in CID font");
     }
     obj1.free();
   }
@@ -1547,7 +1549,7 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
 	  widths.exceps[widths.nExceps].width = obj4.getNum() * 0.001;
 	  ++widths.nExceps;
 	} else {
-	  error(-1, "Bad widths array in Type 0 font");
+	  error(errSyntaxError, -1, "Bad widths array in Type 0 font");
 	}
 	obj4.free();
 	i += 3;
@@ -1567,13 +1569,13 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
 	    ++j;
 	    ++widths.nExceps;
 	  } else {
-	    error(-1, "Bad widths array in Type 0 font");
+	    error(errSyntaxError, -1, "Bad widths array in Type 0 font");
 	  }
 	  obj4.free();
 	}
 	i += 2;
       } else {
-	error(-1, "Bad widths array in Type 0 font");
+	error(errSyntaxError, -1, "Bad widths array in Type 0 font");
 	++i;
       }
       obj3.free();
@@ -1622,7 +1624,7 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
 	  widths.excepsV[widths.nExcepsV].vy = obj6.getNum() * 0.001;
 	  ++widths.nExcepsV;
 	} else {
-	  error(-1, "Bad widths (W2) array in Type 0 font");
+	  error(errSyntaxError, -1, "Bad widths (W2) array in Type 0 font");
 	}
 	obj6.free();
 	obj5.free();
@@ -1649,7 +1651,7 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
 	    ++j;
 	    ++widths.nExcepsV;
 	  } else {
-	    error(-1, "Bad widths (W2) array in Type 0 font");
+	    error(errSyntaxError, -1, "Bad widths (W2) array in Type 0 font");
 	  }
 	  obj6.free();
 	  obj5.free();
@@ -1657,7 +1659,7 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
 	}
 	i += 2;
       } else {
-	error(-1, "Bad widths (W2) array in Type 0 font");
+	error(errSyntaxError, -1, "Bad widths (W2) array in Type 0 font");
 	++i;
       }
       obj3.free();
@@ -1981,8 +1983,8 @@ Gushort *GfxCIDFont::getCodeToGIDMap(FoFiTrueType *ff, int *mapsizep) {
     }
     ff->setupGSUB(lp->scriptTag);
   } else {
-    error(-1,"Unknown character collection %s\n",
-      getCollection()->getCString());
+    error(errSyntaxError, -1, "Unknown character collection {0:t}\n",
+      getCollection());
     if ((ctu = getToUnicode()) != 0) {
       CharCode cid;
       for (cid = 0;cid < n ;cid++) {
@@ -2120,7 +2122,7 @@ GfxFontDict::GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict) {
 	fonts[i] = NULL;
       }
     } else {
-      error(-1, "font resource is not a dictionary");
+      error(errSyntaxError, -1, "font resource is not a dictionary");
       fonts[i] = NULL;
     }
     obj1.free();
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index be73fd8..3e37bdc 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -227,7 +227,7 @@ GfxColorSpace *GfxColorSpace::parse(Object *csObj, Gfx *gfx) {
     } else if (csObj->isName("Pattern")) {
       cs = new GfxPatternColorSpace(NULL);
     } else {
-      error(-1, "Bad color space '%s'", csObj->getName());
+      error(errSyntaxWarning, -1, "Bad color space '{0:s}'", csObj->getName());
     }
   } else if (csObj->isArray()) {
     csObj->arrayGet(0, &obj1);
@@ -254,11 +254,11 @@ GfxColorSpace *GfxColorSpace::parse(Object *csObj, Gfx *gfx) {
     } else if (obj1.isName("Pattern")) {
       cs = GfxPatternColorSpace::parse(csObj->getArray(), gfx);
     } else {
-      error(-1, "Bad color space");
+      error(errSyntaxWarning, -1, "Bad color space");
     }
     obj1.free();
   } else {
-    error(-1, "Bad color space - expected name or array");
+    error(errSyntaxWarning, -1, "Bad color space - expected name or array");
   }
   return cs;
 }
@@ -322,7 +322,7 @@ cmsHPROFILE loadColorProfile(const char *fileName)
 
 static int CMSError(int ecode, const char *msg)
 {
-    error(-1, "%s", msg);
+    error(errSyntaxWarning, -1, "{0:s}", msg);
     return 1;
 }
 
@@ -364,7 +364,7 @@ int GfxColorSpace::setupColorProfiles()
 	   COLORSPACE_SH(displayPixelType) |
 	     CHANNELS_SH(nChannels) | BYTES_SH(1),
 	  INTENT_RELATIVE_COLORIMETRIC,0)) == 0) {
-      error(-1, "Can't create Lab transform");
+      error(errSyntaxWarning, -1, "Can't create Lab transform");
     } else {
       XYZ2DisplayTransform = new GfxColorTransform(transform);
     }
@@ -595,7 +595,7 @@ GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr) {
 
   arr->get(1, &obj1);
   if (!obj1.isDict()) {
-    error(-1, "Bad CalGray color space");
+    error(errSyntaxWarning, -1, "Bad CalGray color space");
     obj1.free();
     return NULL;
   }
@@ -892,7 +892,7 @@ GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) {
 
   arr->get(1, &obj1);
   if (!obj1.isDict()) {
-    error(-1, "Bad CalRGB color space");
+    error(errSyntaxWarning, -1, "Bad CalRGB color space");
     obj1.free();
     return NULL;
   }
@@ -1222,7 +1222,7 @@ GfxColorSpace *GfxLabColorSpace::parse(Array *arr) {
 
   arr->get(1, &obj1);
   if (!obj1.isDict()) {
-    error(-1, "Bad Lab color space");
+    error(errSyntaxWarning, -1, "Bad Lab color space");
     obj1.free();
     return NULL;
   }
@@ -1539,13 +1539,13 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, Gfx *gfx) {
 #endif
   arr->get(1, &obj1);
   if (!obj1.isStream()) {
-    error(-1, "Bad ICCBased color space (stream)");
+    error(errSyntaxWarning, -1, "Bad ICCBased color space (stream)");
     obj1.free();
     return NULL;
   }
   dict = obj1.streamGetDict();
   if (!dict->lookup("N", &obj2)->isInt()) {
-    error(-1, "Bad ICCBased color space (N)");
+    error(errSyntaxWarning, -1, "Bad ICCBased color space (N)");
     obj2.free();
     obj1.free();
     return NULL;
@@ -1553,7 +1553,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, Gfx *gfx) {
   nCompsA = obj2.getInt();
   obj2.free();
   if (nCompsA > gfxColorMaxComps) {
-    error(-1, "ICCBased color space with too many (%d > %d) components",
+    error(errSyntaxWarning, -1, "ICCBased color space with too many ({0:d} > {1:d}) components",
 	  nCompsA, gfxColorMaxComps);
     nCompsA = gfxColorMaxComps;
   }
@@ -1570,7 +1570,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, Gfx *gfx) {
       altA = new GfxDeviceCMYKColorSpace();
       break;
     default:
-      error(-1, "Bad ICCBased color space - invalid N");
+      error(errSyntaxWarning, -1, "Bad ICCBased color space - invalid N");
       obj2.free();
       obj1.free();
       return NULL;
@@ -1606,7 +1606,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, Gfx *gfx) {
   cmsHPROFILE hp = cmsOpenProfileFromMem(profBuf,length);
   gfree(profBuf);
   if (hp == 0) {
-    error(-1, "read ICCBased color space profile error");
+    error(errSyntaxWarning, -1, "read ICCBased color space profile error");
   } else {
     cmsHPROFILE dhp = displayProfile;
     if (dhp == NULL) dhp = RGBProfile;
@@ -1620,7 +1620,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, Gfx *gfx) {
 	   COLORSPACE_SH(dcst) |
 	     CHANNELS_SH(dNChannels) | BYTES_SH(1),
 	  INTENT_RELATIVE_COLORIMETRIC,0)) == 0) {
-      error(-1, "Can't create transform");
+      error(errSyntaxWarning, -1, "Can't create transform");
       cs->transform = NULL;
     } else {
       cs->transform = new GfxColorTransform(transform);
@@ -1630,7 +1630,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, Gfx *gfx) {
       if ((transform = cmsCreateTransform(hp,
 	    CHANNELS_SH(nCompsA) | BYTES_SH(1),dhp,
 	    TYPE_RGB_8,INTENT_RELATIVE_COLORIMETRIC,0)) == 0) {
-	error(-1, "Can't create transform");
+	error(errSyntaxWarning, -1, "Can't create transform");
 	cs->lineTransform = NULL;
       } else {
 	cs->lineTransform = new GfxColorTransform(transform);
@@ -1867,17 +1867,17 @@ GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr, Gfx *gfx) {
   int n, i, j;
 
   if (arr->getLength() != 4) {
-    error(-1, "Bad Indexed color space");
+    error(errSyntaxWarning, -1, "Bad Indexed color space");
     goto err1;
   }
   arr->get(1, &obj1);
   if (!(baseA = GfxColorSpace::parse(&obj1, gfx))) {
-    error(-1, "Bad Indexed color space (base color space)");
+    error(errSyntaxWarning, -1, "Bad Indexed color space (base color space)");
     goto err2;
   }
   obj1.free();
   if (!arr->get(2, &obj1)->isInt()) {
-    error(-1, "Bad Indexed color space (hival)");
+    error(errSyntaxWarning, -1, "Bad Indexed color space (hival)");
     delete baseA;
     goto err2;
   }
@@ -1890,7 +1890,7 @@ GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr, Gfx *gfx) {
     int previousValue = indexHighA;
     if (indexHighA < 0) indexHighA = 0;
     else indexHighA = 255;
-    error(-1, "Bad Indexed color space (invalid indexHigh value, was %d using %d to try to recover)", previousValue, indexHighA);
+    error(errSyntaxWarning, -1, "Bad Indexed color space (invalid indexHigh value, was {0:d} using {1:d} to try to recover)", previousValue, indexHighA);
   }
   obj1.free();
   cs = new GfxIndexedColorSpace(baseA, indexHighA);
@@ -1901,14 +1901,14 @@ GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr, Gfx *gfx) {
     for (i = 0; i <= indexHighA; ++i) {
       const int readChars = obj1.streamGetChars(n, &cs->lookup[i*n]);
       for (j = readChars; j < n; ++j) {
-        error(-1, "Bad Indexed color space (lookup table stream too short) padding with zeroes");
+        error(errSyntaxWarning, -1, "Bad Indexed color space (lookup table stream too short) padding with zeroes");
         cs->lookup[i*n + j] = 0;
       }
     }
     obj1.streamClose();
   } else if (obj1.isString()) {
     if (obj1.getString()->getLength() < (indexHighA + 1) * n) {
-      error(-1, "Bad Indexed color space (lookup table string too short)");
+      error(errSyntaxWarning, -1, "Bad Indexed color space (lookup table string too short)");
       goto err3;
     }
     s = obj1.getString()->getCString();
@@ -1918,7 +1918,7 @@ GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr, Gfx *gfx) {
       }
     }
   } else {
-    error(-1, "Bad Indexed color space (lookup table)");
+    error(errSyntaxWarning, -1, "Bad Indexed color space (lookup table)");
     goto err3;
   }
   obj1.free();
@@ -2055,18 +2055,18 @@ GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr, Gfx *gfx) {
   Object obj1;
 
   if (arr->getLength() != 4) {
-    error(-1, "Bad Separation color space");
+    error(errSyntaxWarning, -1, "Bad Separation color space");
     goto err1;
   }
   if (!arr->get(1, &obj1)->isName()) {
-    error(-1, "Bad Separation color space (name)");
+    error(errSyntaxWarning, -1, "Bad Separation color space (name)");
     goto err2;
   }
   nameA = new GooString(obj1.getName());
   obj1.free();
   arr->get(2, &obj1);
   if (!(altA = GfxColorSpace::parse(&obj1, gfx))) {
-    error(-1, "Bad Separation color space (alternate color space)");
+    error(errSyntaxWarning, -1, "Bad Separation color space (alternate color space)");
     goto err3;
   }
   obj1.free();
@@ -2180,22 +2180,22 @@ GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr, Gfx *gfx) {
   int i;
 
   if (arr->getLength() != 4 && arr->getLength() != 5) {
-    error(-1, "Bad DeviceN color space");
+    error(errSyntaxWarning, -1, "Bad DeviceN color space");
     goto err1;
   }
   if (!arr->get(1, &obj1)->isArray()) {
-    error(-1, "Bad DeviceN color space (names)");
+    error(errSyntaxWarning, -1, "Bad DeviceN color space (names)");
     goto err2;
   }
   nCompsA = obj1.arrayGetLength();
   if (nCompsA > gfxColorMaxComps) {
-    error(-1, "DeviceN color space with too many (%d > %d) components",
+    error(errSyntaxWarning, -1, "DeviceN color space with too many ({0:d} > {1:d}) components",
 	  nCompsA, gfxColorMaxComps);
     nCompsA = gfxColorMaxComps;
   }
   for (i = 0; i < nCompsA; ++i) {
     if (!obj1.arrayGet(i, &obj2)->isName()) {
-      error(-1, "Bad DeviceN color space (names)");
+      error(errSyntaxWarning, -1, "Bad DeviceN color space (names)");
       obj2.free();
       goto err2;
     }
@@ -2205,7 +2205,7 @@ GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr, Gfx *gfx) {
   obj1.free();
   arr->get(2, &obj1);
   if (!(altA = GfxColorSpace::parse(&obj1, gfx))) {
-    error(-1, "Bad DeviceN color space (alternate color space)");
+    error(errSyntaxWarning, -1, "Bad DeviceN color space (alternate color space)");
     goto err3;
   }
   obj1.free();
@@ -2314,14 +2314,14 @@ GfxColorSpace *GfxPatternColorSpace::parse(Array *arr, Gfx *gfx) {
   Object obj1;
 
   if (arr->getLength() != 1 && arr->getLength() != 2) {
-    error(-1, "Bad Pattern color space");
+    error(errSyntaxWarning, -1, "Bad Pattern color space");
     return NULL;
   }
   underA = NULL;
   if (arr->getLength() == 2) {
     arr->get(1, &obj1);
     if (!(underA = GfxColorSpace::parse(&obj1, gfx))) {
-      error(-1, "Bad Pattern color space (underlying color space)");
+      error(errSyntaxWarning, -1, "Bad Pattern color space (underlying color space)");
       obj1.free();
       return NULL;
     }
@@ -2403,14 +2403,14 @@ GfxTilingPattern *GfxTilingPattern::parse(Object *patObj) {
     paintTypeA = obj1.getInt();
   } else {
     paintTypeA = 1;
-    error(-1, "Invalid or missing PaintType in pattern");
+    error(errSyntaxWarning, -1, "Invalid or missing PaintType in pattern");
   }
   obj1.free();
   if (dict->lookup("TilingType", &obj1)->isInt()) {
     tilingTypeA = obj1.getInt();
   } else {
     tilingTypeA = 1;
-    error(-1, "Invalid or missing TilingType in pattern");
+    error(errSyntaxWarning, -1, "Invalid or missing TilingType in pattern");
   }
   obj1.free();
   bboxA[0] = bboxA[1] = 0;
@@ -2424,27 +2424,27 @@ GfxTilingPattern *GfxTilingPattern::parse(Object *patObj) {
       obj2.free();
     }
   } else {
-    error(-1, "Invalid or missing BBox in pattern");
+    error(errSyntaxWarning, -1, "Invalid or missing BBox in pattern");
   }
   obj1.free();
   if (dict->lookup("XStep", &obj1)->isNum()) {
     xStepA = obj1.getNum();
   } else {
     xStepA = 1;
-    error(-1, "Invalid or missing XStep in pattern");
+    error(errSyntaxWarning, -1, "Invalid or missing XStep in pattern");
   }
   obj1.free();
   if (dict->lookup("YStep", &obj1)->isNum()) {
     yStepA = obj1.getNum();
   } else {
     yStepA = 1;
-    error(-1, "Invalid or missing YStep in pattern");
+    error(errSyntaxWarning, -1, "Invalid or missing YStep in pattern");
   }
   obj1.free();
   if (!dict->lookup("Resources", &resDictA)->isDict()) {
     resDictA.free();
     resDictA.initNull();
-    error(-1, "Invalid or missing Resources in pattern");
+    error(errSyntaxWarning, -1, "Invalid or missing Resources in pattern");
   }
   matrixA[0] = 1; matrixA[1] = 0;
   matrixA[2] = 0; matrixA[3] = 1;
@@ -2603,7 +2603,7 @@ GfxShading *GfxShading::parse(Object *obj, Gfx *gfx) {
   }
 
   if (!dict->lookup("ShadingType", &obj1)->isInt()) {
-    error(-1, "Invalid ShadingType in shading dictionary");
+    error(errSyntaxWarning, -1, "Invalid ShadingType in shading dictionary");
     obj1.free();
     return NULL;
   }
@@ -2624,7 +2624,7 @@ GfxShading *GfxShading::parse(Object *obj, Gfx *gfx) {
     if (obj->isStream()) {
       shading = GfxGouraudTriangleShading::parse(4, dict, obj->getStream(), gfx);
     } else {
-      error(-1, "Invalid Type 4 shading object");
+      error(errSyntaxWarning, -1, "Invalid Type 4 shading object");
       goto err1;
     }
     break;
@@ -2632,7 +2632,7 @@ GfxShading *GfxShading::parse(Object *obj, Gfx *gfx) {
     if (obj->isStream()) {
       shading = GfxGouraudTriangleShading::parse(5, dict, obj->getStream(), gfx);
     } else {
-      error(-1, "Invalid Type 5 shading object");
+      error(errSyntaxWarning, -1, "Invalid Type 5 shading object");
       goto err1;
     }
     break;
@@ -2640,7 +2640,7 @@ GfxShading *GfxShading::parse(Object *obj, Gfx *gfx) {
     if (obj->isStream()) {
       shading = GfxPatchMeshShading::parse(6, dict, obj->getStream(), gfx);
     } else {
-      error(-1, "Invalid Type 6 shading object");
+      error(errSyntaxWarning, -1, "Invalid Type 6 shading object");
       goto err1;
     }
     break;
@@ -2648,12 +2648,12 @@ GfxShading *GfxShading::parse(Object *obj, Gfx *gfx) {
     if (obj->isStream()) {
       shading = GfxPatchMeshShading::parse(7, dict, obj->getStream(), gfx);
     } else {
-      error(-1, "Invalid Type 7 shading object");
+      error(errSyntaxWarning, -1, "Invalid Type 7 shading object");
       goto err1;
     }
     break;
   default:
-    error(-1, "Unimplemented shading type %d", typeA);
+    error(errSyntaxWarning, -1, "Unimplemented shading type {0:d}", typeA);
     goto err1;
   }
 
@@ -2669,7 +2669,7 @@ GBool GfxShading::init(Dict *dict, Gfx *gfx) {
 
   dict->lookup("ColorSpace", &obj1);
   if (!(colorSpace = GfxColorSpace::parse(&obj1, gfx))) {
-    error(-1, "Bad color space in shading dictionary");
+    error(errSyntaxWarning, -1, "Bad color space in shading dictionary");
     obj1.free();
     return gFalse;
   }
@@ -2687,7 +2687,7 @@ GBool GfxShading::init(Dict *dict, Gfx *gfx) {
 	obj2.free();
       }
     } else {
-      error(-1, "Bad Background in shading dictionary");
+      error(errSyntaxWarning, -1, "Bad Background in shading dictionary");
     }
   }
   obj1.free();
@@ -2709,14 +2709,14 @@ GBool GfxShading::init(Dict *dict, Gfx *gfx) {
         xMax = obj4.getNum();
         yMax = obj5.getNum();
       } else {
-        error(-1, "Bad BBox in shading dictionary (Values not numbers)");
+        error(errSyntaxWarning, -1, "Bad BBox in shading dictionary (Values not numbers)");
       }
       obj2.free();
       obj3.free();
       obj4.free();
       obj5.free();
     } else {
-      error(-1, "Bad BBox in shading dictionary");
+      error(errSyntaxWarning, -1, "Bad BBox in shading dictionary");
     }
   }
   obj1.free();
@@ -2823,7 +2823,7 @@ GfxFunctionShading *GfxFunctionShading::parse(Dict *dict, Gfx *gfx) {
   if (obj1.isArray()) {
     nFuncsA = obj1.arrayGetLength();
     if (nFuncsA > gfxColorMaxComps) {
-      error(-1, "Invalid Function array in shading dictionary");
+      error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
       goto err1;
     }
     for (i = 0; i < nFuncsA; ++i) {
@@ -3119,7 +3119,7 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict, Gfx *gfx) {
     obj4.free();
     obj5.free();
   } else {
-    error(-1, "Missing or invalid Coords in shading dictionary");
+    error(errSyntaxWarning, -1, "Missing or invalid Coords in shading dictionary");
     goto err1;
   }
   obj1.free();
@@ -3144,7 +3144,7 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict, Gfx *gfx) {
   if (obj1.isArray()) {
     nFuncsA = obj1.arrayGetLength();
     if (nFuncsA > gfxColorMaxComps) {
-      error(-1, "Invalid Function array in shading dictionary");
+      error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
       goto err1;
     }
     for (i = 0; i < nFuncsA; ++i) {
@@ -3314,7 +3314,7 @@ GfxRadialShading *GfxRadialShading::parse(Dict *dict, Gfx *gfx) {
     r1A = obj1.arrayGet(5, &obj2)->getNum();
     obj2.free();
   } else {
-    error(-1, "Missing or invalid Coords in shading dictionary");
+    error(errSyntaxWarning, -1, "Missing or invalid Coords in shading dictionary");
     goto err1;
   }
   obj1.free();
@@ -3334,7 +3334,7 @@ GfxRadialShading *GfxRadialShading::parse(Dict *dict, Gfx *gfx) {
   if (obj1.isArray()) {
     nFuncsA = obj1.arrayGetLength();
     if (nFuncsA > gfxColorMaxComps) {
-      error(-1, "Invalid Function array in shading dictionary");
+      error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
       goto err1;
     }
     for (i = 0; i < nFuncsA; ++i) {
@@ -3832,14 +3832,14 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(int typeA,
   if (dict->lookup("BitsPerCoordinate", &obj1)->isInt()) {
     coordBits = obj1.getInt();
   } else {
-    error(-1, "Missing or invalid BitsPerCoordinate in shading dictionary");
+    error(errSyntaxWarning, -1, "Missing or invalid BitsPerCoordinate in shading dictionary");
     goto err2;
   }
   obj1.free();
   if (dict->lookup("BitsPerComponent", &obj1)->isInt()) {
     compBits = obj1.getInt();
   } else {
-    error(-1, "Missing or invalid BitsPerComponent in shading dictionary");
+    error(errSyntaxWarning, -1, "Missing or invalid BitsPerComponent in shading dictionary");
     goto err2;
   }
   obj1.free();
@@ -3848,7 +3848,7 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(int typeA,
     if (dict->lookup("BitsPerFlag", &obj1)->isInt()) {
       flagBits = obj1.getInt();
     } else {
-      error(-1, "Missing or invalid BitsPerFlag in shading dictionary");
+      error(errSyntaxWarning, -1, "Missing or invalid BitsPerFlag in shading dictionary");
       goto err2;
     }
     obj1.free();
@@ -3856,7 +3856,7 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(int typeA,
     if (dict->lookup("VerticesPerRow", &obj1)->isInt()) {
       vertsPerRow = obj1.getInt();
     } else {
-      error(-1, "Missing or invalid VerticesPerRow in shading dictionary");
+      error(errSyntaxWarning, -1, "Missing or invalid VerticesPerRow in shading dictionary");
       goto err2;
     }
     obj1.free();
@@ -3882,7 +3882,7 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(int typeA,
     }
     nComps = i;
   } else {
-    error(-1, "Missing or invalid Decode array in shading dictionary");
+    error(errSyntaxWarning, -1, "Missing or invalid Decode array in shading dictionary");
     goto err2;
   }
   obj1.free();
@@ -3891,7 +3891,7 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(int typeA,
     if (obj1.isArray()) {
       nFuncsA = obj1.arrayGetLength();
       if (nFuncsA > gfxColorMaxComps) {
-	error(-1, "Invalid Function array in shading dictionary");
+	error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
 	goto err1;
       }
       for (i = 0; i < nFuncsA; ++i) {
@@ -4177,21 +4177,21 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
   if (dict->lookup("BitsPerCoordinate", &obj1)->isInt()) {
     coordBits = obj1.getInt();
   } else {
-    error(-1, "Missing or invalid BitsPerCoordinate in shading dictionary");
+    error(errSyntaxWarning, -1, "Missing or invalid BitsPerCoordinate in shading dictionary");
     goto err2;
   }
   obj1.free();
   if (dict->lookup("BitsPerComponent", &obj1)->isInt()) {
     compBits = obj1.getInt();
   } else {
-    error(-1, "Missing or invalid BitsPerComponent in shading dictionary");
+    error(errSyntaxWarning, -1, "Missing or invalid BitsPerComponent in shading dictionary");
     goto err2;
   }
   obj1.free();
   if (dict->lookup("BitsPerFlag", &obj1)->isInt()) {
     flagBits = obj1.getInt();
   } else {
-    error(-1, "Missing or invalid BitsPerFlag in shading dictionary");
+    error(errSyntaxWarning, -1, "Missing or invalid BitsPerFlag in shading dictionary");
     goto err2;
   }
   obj1.free();
@@ -4216,7 +4216,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
     }
     nComps = i;
   } else {
-    error(-1, "Missing or invalid Decode array in shading dictionary");
+    error(errSyntaxWarning, -1, "Missing or invalid Decode array in shading dictionary");
     goto err2;
   }
   obj1.free();
@@ -4225,7 +4225,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
     if (obj1.isArray()) {
       nFuncsA = obj1.arrayGetLength();
       if (nFuncsA > gfxColorMaxComps) {
-	error(-1, "Invalid Function array in shading dictionary");
+	error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
 	goto err1;
       }
       for (i = 0; i < nFuncsA; ++i) {
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 3d692a1..eb409e9 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -202,10 +202,10 @@ public:
   virtual void getGray(GfxColor *color, GfxGray *gray) = 0;
   virtual void getRGB(GfxColor *color, GfxRGB *rgb) = 0;
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0;
-  virtual void getGrayLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) { error(-1, "GfxColorSpace::getGrayLine this should not happen"); }
-  virtual void getRGBLine(Guchar * /*in*/, unsigned int * /*out*/, int /*length*/) { error(-1, "GfxColorSpace::getRGBLine (first variant) this should not happen"); }
-  virtual void getRGBLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) {  error(-1, "GfxColorSpace::getRGBLine (second variant) this should not happen"); }
-  virtual void getRGBXLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) {  error(-1, "GfxColorSpace::getRGBXLine this should not happen"); }
+  virtual void getGrayLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) { error(errInternal, -1, "GfxColorSpace::getGrayLine this should not happen"); }
+  virtual void getRGBLine(Guchar * /*in*/, unsigned int * /*out*/, int /*length*/) { error(errInternal, -1, "GfxColorSpace::getRGBLine (first variant) this should not happen"); }
+  virtual void getRGBLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) {  error(errInternal, -1, "GfxColorSpace::getRGBLine (second variant) this should not happen"); }
+  virtual void getRGBXLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) {  error(errInternal, -1, "GfxColorSpace::getRGBXLine this should not happen"); }
 
   // Does this ColorSpace support getRGBLine?
   virtual GBool useGetRGBLine() { return gFalse; }
diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc
index 9bb3b64..f49950d 100644
--- a/poppler/GlobalParams.cc
+++ b/poppler/GlobalParams.cc
@@ -517,33 +517,32 @@ Plugin *Plugin::load(char *type, char *name) {
 #ifdef _WIN32
   path->append(".dll");
   if (!(libA = LoadLibrary(path->getCString()))) {
-    error(-1, "Failed to load plugin '%s'",
-	  path->getCString());
+    error(errIO, -1, "Failed to load plugin '{0:t}'", path);
     goto err1;
   }
   if (!(vt = (XpdfPluginVecTable *)
 	         GetProcAddress(libA, "xpdfPluginVecTable"))) {
-    error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
-	  path->getCString());
+    error(errIO, -1, "Failed to find xpdfPluginVecTable in plugin '{0:t}'",
+	  path);
     goto err2;
   }
 #else
   //~ need to deal with other extensions here
   path->append(".so");
   if (!(dlA = dlopen(path->getCString(), RTLD_NOW))) {
-    error(-1, "Failed to load plugin '%s': %s",
-	  path->getCString(), dlerror());
+    error(errIO, -1, "Failed to load plugin '{0:t}': {1:s}",
+	  path, dlerror());
     goto err1;
   }
   if (!(vt = (XpdfPluginVecTable *)dlsym(dlA, "xpdfPluginVecTable"))) {
-    error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
-	  path->getCString());
+    error(errIO, -1, "Failed to find xpdfPluginVecTable in plugin '{0:t}'",
+	  path);
     goto err2;
   }
 #endif
 
   if (vt->version != xpdfPluginVecTable.version) {
-    error(-1, "Plugin '%s' is wrong version", path->getCString());
+    error(errIO, -1, "Plugin '{0:t}' is wrong version", path);
     goto err2;
   }
   memcpy(vt, &xpdfPluginVecTable, sizeof(xpdfPluginVecTable));
@@ -551,21 +550,20 @@ Plugin *Plugin::load(char *type, char *name) {
 #ifdef _WIN32
   if (!(xpdfInitPlugin = (XpdfBool (*)(void))
 	                     GetProcAddress(libA, "xpdfInitPlugin"))) {
-    error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
-	  path->getCString());
+    error(errIO, -1, "Failed to find xpdfInitPlugin in plugin '{0:t}'",
+	  path);
     goto err2;
   }
 #else
   if (!(xpdfInitPlugin = (XpdfBool (*)(void))dlsym(dlA, "xpdfInitPlugin"))) {
-    error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
-	  path->getCString());
+    error(errIO, -1, "Failed to find xpdfInitPlugin in plugin '{0:t}'",
+	  path);
     goto err2;
   }
 #endif
 
   if (!(*xpdfInitPlugin)()) {
-    error(-1, "Initialization of plugin '%s' failed",
-	  path->getCString());
+    error(errIO, -1, "Initialization of plugin '{0:t}' failed", path);
     goto err2;
   }
 
@@ -801,8 +799,8 @@ void GlobalParams::parseNameToUnicode(GooString *name) {
   char *tokptr;
 
   if (!(f = fopen(name->getCString(), "r"))) {
-    error(-1, "Couldn't open 'nameToUnicode' file '%s'",
-	  name->getCString());
+    error(errIO, -1, "Couldn't open 'nameToUnicode' file '{0:t}'",
+	  name);
     return;
   }
   line = 1;
@@ -813,8 +811,8 @@ void GlobalParams::parseNameToUnicode(GooString *name) {
       sscanf(tok1, "%x", &u);
       nameToUnicode->add(tok2, u);
     } else {
-      error(-1, "Bad line in 'nameToUnicode' file (%s:%d)",
-	    name->getCString(), line);
+      error(errConfig, -1, "Bad line in 'nameToUnicode' file ({0:t}:{1:d})",
+	    name, line);
     }
     ++line;
   }
@@ -1058,7 +1056,7 @@ static const char *getFontLang(GfxFont *font)
         lang = "xx";
       else
       {
-        error(-1, "Unknown CID font collection, please report to poppler bugzilla.");
+        error(errUnimplemented, -1, "Unknown CID font collection, please report to poppler bugzilla.");
         lang = "xx";
       }
     }
diff --git a/poppler/GlobalParamsWin.cc b/poppler/GlobalParamsWin.cc
index b316946..23ea619 100644
--- a/poppler/GlobalParamsWin.cc
+++ b/poppler/GlobalParamsWin.cc
@@ -257,7 +257,7 @@ void GlobalParams::setupBaseFonts(char * dir)
             delete fontPath;
         }
 
-        error(-1, "No display font for '%s'", fontName);
+        error(errSyntaxError, -1, "No display font for '{0:s}'", fontName);
     }
 }
 
@@ -281,7 +281,7 @@ DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) {
     dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
     if (!dfp) {
         substFontName = findSubstituteName(fontName->getCString());
-        error(-1, "Couldn't find a font for '%s', subst is '%s'", fontName->getCString(), substFontName);
+        error(errSyntaxError, -1, "Couldn't find a font for '{0:t}', subst is '{0:s}'", fontName, substFontName);
         dfp = (DisplayFontParam *)displayFonts->lookup(substFontName);
         assert(dfp);
     }
diff --git a/poppler/Hints.cc b/poppler/Hints.cc
index 4f0c959..df066c6 100644
--- a/poppler/Hints.cc
+++ b/poppler/Hints.cc
@@ -36,7 +36,7 @@ Hints::Hints(BaseStream *str, Linearization *linearization, XRef *xref, Security
   pageEndFirst = linearization->getEndFirst();
   pageObjectFirst = linearization->getObjectNumberFirst();
   if (pageObjectFirst < 0 || pageObjectFirst >= xref->getNumObjects()) {
-    error(-1,
+    error(errSyntaxWarning, -1,
       "Invalid reference for first page object (%d) in linearization table ",
       pageObjectFirst);
     pageObjectFirst = 0;
@@ -44,7 +44,7 @@ Hints::Hints(BaseStream *str, Linearization *linearization, XRef *xref, Security
   pageOffsetFirst = xref->getEntry(pageObjectFirst)->offset;
 
   if (nPages >= INT_MAX / (int)sizeof(Guint)) {
-     error(-1, "Invalid number of pages (%d) for hints table", nPages);
+     error(errSyntaxWarning, -1, "Invalid number of pages ({0:d}) for hints table", nPages);
      nPages = 0;
   }
   nObjects = (Guint *) gmallocn_checkoverflow(nPages, sizeof(Guint));
@@ -56,7 +56,7 @@ Hints::Hints(BaseStream *str, Linearization *linearization, XRef *xref, Security
   sharedObjectId = (Guint **) gmallocn_checkoverflow(nPages, sizeof(Guint*));
   if (!nObjects || !pageObjectNum || !xRefOffset || !pageLength || !pageOffset ||
       !numSharedObject || !sharedObjectId) {
-    error(-1, "Failed to allocate memory for hints tabel");
+    error(errSyntaxWarning, -1, "Failed to allocate memory for hints tabel");
     nPages = 0;
   }
 
@@ -153,10 +153,10 @@ void Hints::readTables(BaseStream *str, Linearization *linearization, XRef *xref
         for (int i=0; i<sharedStreamOffset; i++) hintsStream->getChar();
         readSharedObjectsTable(hintsStream);
     } else {
-      error(-1, "Invalid shared object hint table offset");
+      error(errSyntaxWarning, -1, "Invalid shared object hint table offset");
     }
   } else {
-    error(-1, "Failed parsing hints table object");
+    error(errSyntaxWarning, -1, "Failed parsing hints table object");
   }
   obj.free();
 
@@ -166,7 +166,7 @@ void Hints::readTables(BaseStream *str, Linearization *linearization, XRef *xref
 void Hints::readPageOffsetTable(Stream *str)
 {
   if (nPages < 1) {
-    error(-1, "Invalid number of pages reading page offset hints table");
+    error(errSyntaxWarning, -1, "Invalid number of pages reading page offset hints table");
     return;
   }
 
@@ -227,13 +227,13 @@ void Hints::readPageOffsetTable(Stream *str)
   for (int i=1; i<nPages; i++) {
     numSharedObject[i] = readBits(nBitsNumShared, str);
     if (numSharedObject[i] >= INT_MAX / (int)sizeof(Guint)) {
-       error(-1, "Invalid number of shared objects");
+       error(errSyntaxWarning, -1, "Invalid number of shared objects");
        numSharedObject[i] = 0;
        return;
     }
     sharedObjectId[i] = (Guint *) gmallocn_checkoverflow(numSharedObject[i], sizeof(Guint));
     if (numSharedObject[i] && !sharedObjectId[i]) {
-       error(-1, "Failed to allocate memory for shared object IDs");
+       error(errSyntaxWarning, -1, "Failed to allocate memory for shared object IDs");
        numSharedObject[i] = 0;
        return;
     }
@@ -274,12 +274,12 @@ void Hints::readSharedObjectsTable(Stream *str)
   Guint nBitsDiffGroupLength = readBits(16, str);
 
   if ((!nSharedGroups) || (nSharedGroups >= INT_MAX / (int)sizeof(Guint))) {
-     error(-1, "Invalid number of shared object groups");
+     error(errSyntaxWarning, -1, "Invalid number of shared object groups");
      nSharedGroups = 0;
      return;
   }
   if ((!nSharedGroupsFirst) || (nSharedGroupsFirst > nSharedGroups)) {
-     error(-1, "Invalid number of first page shared object groups");
+     error(errSyntaxWarning, -1, "Invalid number of first page shared object groups");
      nSharedGroupsFirst = nSharedGroups;
   }
 
@@ -290,7 +290,7 @@ void Hints::readSharedObjectsTable(Stream *str)
   groupXRefOffset = (Guint *) gmallocn_checkoverflow(nSharedGroups, sizeof(Guint));
   if (!groupLength || !groupOffset || !groupHasSignature ||
       !groupNumObjects || !groupXRefOffset) {
-     error(-1, "Failed to allocate memory for shared object groups");
+     error(errSyntaxWarning, -1, "Failed to allocate memory for shared object groups");
      nSharedGroups = 0;
      return;
   }
diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index ba02b14..0c40950 100644
--- a/poppler/JBIG2Stream.cc
+++ b/poppler/JBIG2Stream.cc
@@ -510,7 +510,7 @@ int JBIG2MMRDecoder::get2DCode() {
     }
   }
   if (p->bits < 0) {
-    error(str->getPos(), "Bad two dim code in JBIG2 MMR stream");
+    error(errSyntaxError, str->getPos(), "Bad two dim code in JBIG2 MMR stream");
     return EOF;
   }
   bufLen -= p->bits;
@@ -553,7 +553,7 @@ int JBIG2MMRDecoder::getWhiteCode() {
     bufLen += 8;
     ++nBytesRead;
   }
-  error(str->getPos(), "Bad white code in JBIG2 MMR stream");
+  error(errSyntaxError, str->getPos(), "Bad white code in JBIG2 MMR stream");
   // eat a bit and return a positive number so that the caller doesn't
   // go into an infinite loop
   --bufLen;
@@ -604,7 +604,7 @@ int JBIG2MMRDecoder::getBlackCode() {
     bufLen += 8;
     ++nBytesRead;
   }
-  error(str->getPos(), "Bad black code in JBIG2 MMR stream");
+  error(errSyntaxError, str->getPos(), "Bad black code in JBIG2 MMR stream");
   // eat a bit and return a positive number so that the caller doesn't
   // go into an infinite loop
   --bufLen;
@@ -706,7 +706,7 @@ JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA):
   line = (wA + 7) >> 3;
 
   if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
-    error(-1, "invalid width/height");
+    error(errSyntaxError, -1, "invalid width/height");
     data = NULL;
     return;
   }
@@ -723,7 +723,7 @@ JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
   line = bitmap->line;
 
   if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
-    error(-1, "invalid width/height");
+    error(errSyntaxError, -1, "invalid width/height");
     data = NULL;
     return;
   }
@@ -761,7 +761,7 @@ JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
 
 void JBIG2Bitmap::expand(int newH, Guint pixel) {
   if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
-    error(-1, "invalid width/height");
+    error(errSyntaxError, -1, "invalid width/height");
     gfree(data);
     data = NULL;
     return;
@@ -1352,7 +1352,7 @@ void JBIG2Stream::readSegments() {
     // check for missing page information segment
     if (!pageBitmap && ((segType >= 4 && segType <= 7) ||
 			(segType >= 20 && segType <= 43))) {
-      error(curStr->getPos(), "First JBIG2 segment associated with a page must be a page information segment");
+      error(errSyntaxError, curStr->getPos(), "First JBIG2 segment associated with a page must be a page information segment");
       goto syntaxError;
     }
 
@@ -1424,7 +1424,7 @@ void JBIG2Stream::readSegments() {
       readExtensionSeg(segLength);
       break;
     default:
-      error(curStr->getPos(), "Unknown segment type in JBIG2 stream");
+      error(errSyntaxError, curStr->getPos(), "Unknown segment type in JBIG2 stream");
       for (i = 0; i < segLength; ++i) {
 	if ((c1 = curStr->getChar()) == EOF) {
 	  goto eofError2;
@@ -1450,7 +1450,7 @@ void JBIG2Stream::readSegments() {
 	// arithmetic-coded symbol dictionary segments when numNewSyms
 	// == 0.  Segments like this often occur for blank pages.
 	
-	error(curStr->getPos(), "%d extraneous byte%s after segment",
+	error(errSyntaxError, curStr->getPos(), "{0:d} extraneous byte{1:s} after segment",
 	      segExtraBytes, (segExtraBytes > 1) ? "s" : "");
 	
 	// Burn through the remaining bytes -- inefficient, but
@@ -1466,7 +1466,7 @@ void JBIG2Stream::readSegments() {
 	// If we read more bytes than we should have, according to the 
 	// segment length field, note an error.
 	
-	error(curStr->getPos(), "Previous segment handler read too many bytes");
+	error(errSyntaxError, curStr->getPos(), "Previous segment handler read too many bytes");
 	
       }
 
@@ -1484,7 +1484,7 @@ void JBIG2Stream::readSegments() {
  eofError2:
   gfree(refSegs);
  eofError1:
-  error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
+  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
 }
 
 GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
@@ -1574,7 +1574,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
       if (seg->getType() == jbig2SegSymbolDict) {
 	j = ((JBIG2SymbolDict *)seg)->getSize();
 	if (numInputSyms > UINT_MAX - j) {
-	  error(curStr->getPos(), "Too many input symbols in JBIG2 symbol dictionary");
+	  error(errSyntaxError, curStr->getPos(), "Too many input symbols in JBIG2 symbol dictionary");
 	  delete codeTables;
 	  goto eofError;
 	}
@@ -1588,7 +1588,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
     }
   }
   if (numInputSyms > UINT_MAX - numNewSyms) {
-    error(curStr->getPos(), "Too many input symbols in JBIG2 symbol dictionary");
+    error(errSyntaxError, curStr->getPos(), "Too many input symbols in JBIG2 symbol dictionary");
     delete codeTables;
     goto eofError;
   }
@@ -1709,7 +1709,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
       arithDecoder->decodeInt(&dh, iadhStats);
     }
     if (dh < 0 && (Guint)-dh >= symHeight) {
-      error(curStr->getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
+      error(errSyntaxError, curStr->getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
       goto syntaxError;
     }
     symHeight += dh;
@@ -1731,12 +1731,12 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
 	}
       }
       if (dw < 0 && (Guint)-dw >= symWidth) {
-	error(curStr->getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
+	error(errSyntaxError, curStr->getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
 	goto syntaxError;
       }
       symWidth += dw;
       if (i >= numNewSyms) {
-	error(curStr->getPos(), "Too many symbols in JBIG2 symbol dictionary");
+	error(errSyntaxError, curStr->getPos(), "Too many symbols in JBIG2 symbol dictionary");
 	goto syntaxError;
       }
 
@@ -1776,7 +1776,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
 	    arithDecoder->decodeInt(&refDY, iardyStats);
 	  }
 	  if (symID >= numInputSyms + i) {
-	    error(curStr->getPos(), "Invalid symbol ID in JBIG2 symbol dictionary");
+	    error(errSyntaxError, curStr->getPos(), "Invalid symbol ID in JBIG2 symbol dictionary");
 	    goto syntaxError;
 	  }
 	  refBitmap = bitmaps[symID];
@@ -1851,7 +1851,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
     }
     if (i + run > numInputSyms + numNewSyms ||
 	(ex && j + run > numExSyms)) {
-      error(curStr->getPos(), "Too many exported symbols in JBIG2 symbol dictionary");
+      error(errSyntaxError, curStr->getPos(), "Too many exported symbols in JBIG2 symbol dictionary");
       for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
       delete symbolDict;
       goto syntaxError;
@@ -1866,7 +1866,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
     ex = !ex;
   }
   if (j != numExSyms) {
-    error(curStr->getPos(), "Too few symbols in JBIG2 symbol dictionary");
+    error(errSyntaxError, curStr->getPos(), "Too few symbols in JBIG2 symbol dictionary");
     for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
     delete symbolDict;
     goto syntaxError;
@@ -1894,7 +1894,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
   return gTrue;
 
  codeTableError:
-  error(curStr->getPos(), "Missing code table in JBIG2 symbol dictionary");
+  error(errSyntaxError, curStr->getPos(), "Missing code table in JBIG2 symbol dictionary");
   delete codeTables;
 
  syntaxError:
@@ -1910,7 +1910,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
   return gFalse;
 
  eofError:
-  error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
+  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
   return gFalse;
 }
 
@@ -1998,7 +1998,7 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
 	codeTables->append(seg);
       }
     } else {
-      error(curStr->getPos(), "Invalid segment reference in JBIG2 text region");
+      error(errSyntaxError, curStr->getPos(), "Invalid segment reference in JBIG2 text region");
       delete codeTables;
       return;
     }
@@ -2207,13 +2207,13 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
   return;
 
  codeTableError:
-  error(curStr->getPos(), "Missing code table in JBIG2 text region");
+  error(errSyntaxError, curStr->getPos(), "Missing code table in JBIG2 text region");
   gfree(codeTables);
   delete syms;
   return;
 
  eofError:
-  error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
+  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
   return;
 }
 
@@ -2314,7 +2314,7 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
       }
 
       if (symID >= (Guint)numSyms) {
-	error(curStr->getPos(), "Invalid symbol number in JBIG2 text region");
+	error(errSyntaxError, curStr->getPos(), "Invalid symbol number in JBIG2 text region");
       } else {
 
 	// get the symbol bitmap
@@ -2484,7 +2484,7 @@ void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
   return;
 
  eofError:
-  error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
+  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
 }
 
 void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
@@ -2526,22 +2526,22 @@ void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
     goto eofError;
   }
   if (w == 0 || h == 0 || w >= INT_MAX / h) {
-    error(curStr->getPos(), "Bad bitmap size in JBIG2 halftone segment");
+    error(errSyntaxError, curStr->getPos(), "Bad bitmap size in JBIG2 halftone segment");
     return;
   }
   if (gridH == 0 || gridW >= INT_MAX / gridH) {
-    error(curStr->getPos(), "Bad grid size in JBIG2 halftone segment");
+    error(errSyntaxError, curStr->getPos(), "Bad grid size in JBIG2 halftone segment");
     return;
   }
 
   // get pattern dictionary
   if (nRefSegs != 1) {
-    error(curStr->getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
+    error(errSyntaxError, curStr->getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
     return;
   }
   seg = findSegment(refSegs[0]);
   if (seg == NULL || seg->getType() != jbig2SegPatternDict) {
-    error(curStr->getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
+    error(errSyntaxError, curStr->getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
     return;
   }
 
@@ -2644,7 +2644,7 @@ void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
   return;
 
  eofError:
-  error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
+  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
 }
 
 void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
@@ -2720,14 +2720,14 @@ void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
   return;
 
  eofError:
-  error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
+  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
 }
 
 inline void JBIG2Stream::mmrAddPixels(int a1, int blackPixels,
 				      int *codingLine, int *a0i, int w) {
   if (a1 > codingLine[*a0i]) {
     if (a1 > w) {
-      error(curStr->getPos(), "JBIG2 MMR row is wrong length (%d)", a1);
+      error(errSyntaxError, curStr->getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
       a1 = w;
     }
     if ((*a0i & 1) ^ blackPixels) {
@@ -2741,7 +2741,7 @@ inline void JBIG2Stream::mmrAddPixelsNeg(int a1, int blackPixels,
 					 int *codingLine, int *a0i, int w) {
   if (a1 > codingLine[*a0i]) {
     if (a1 > w) {
-      error(curStr->getPos(), "JBIG2 MMR row is wrong length (%d)", a1);
+      error(errSyntaxError, curStr->getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
       a1 = w;
     }
     if ((*a0i & 1) ^ blackPixels) {
@@ -2750,7 +2750,7 @@ inline void JBIG2Stream::mmrAddPixelsNeg(int a1, int blackPixels,
     codingLine[*a0i] = a1;
   } else if (a1 < codingLine[*a0i]) {
     if (a1 < 0) {
-      error(curStr->getPos(), "Invalid JBIG2 MMR code");
+      error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 MMR code");
       a1 = 0;
     }
     while (*a0i > 0 && a1 <= codingLine[*a0i - 1]) {
@@ -2787,7 +2787,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
 
     mmrDecoder->reset();
     if (w > INT_MAX - 2) {
-      error(curStr->getPos(), "Bad width in JBIG2 generic bitmap");
+      error(errSyntaxError, curStr->getPos(), "Bad width in JBIG2 generic bitmap");
       // force a call to gmalloc(-1), which will throw an exception
       w = -3;
     }
@@ -2941,7 +2941,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
           mmrAddPixels(w, 0, codingLine, &a0i, w);
           break;
 	default:
-	  error(curStr->getPos(), "Illegal code in JBIG2 MMR bitmap data");
+	  error(errSyntaxError, curStr->getPos(), "Illegal code in JBIG2 MMR bitmap data");
           mmrAddPixels(w, 0, codingLine, &a0i, w);
 	  break;
 	}
@@ -2964,7 +2964,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
       mmrDecoder->skipTo(mmrDataLength);
     } else {
       if (mmrDecoder->get24Bits() != 0x001001) {
-	error(curStr->getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
+	error(errSyntaxError, curStr->getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
       }
     }
 
@@ -3204,13 +3204,13 @@ void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
 
   // get referenced bitmap
   if (nRefSegs > 1) {
-    error(curStr->getPos(), "Bad reference in JBIG2 generic refinement segment");
+    error(errSyntaxError, curStr->getPos(), "Bad reference in JBIG2 generic refinement segment");
     return;
   }
   if (nRefSegs == 1) {
     seg = findSegment(refSegs[0]);
     if (seg == NULL || seg->getType() != jbig2SegBitmap) {
-      error(curStr->getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
+      error(errSyntaxError, curStr->getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
       return;
     }
     refBitmap = (JBIG2Bitmap *)seg;
@@ -3237,7 +3237,7 @@ void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
       bitmap->setSegNum(segNum);
       segments->append(bitmap);
     } else {
-      error(curStr->getPos(), "readGenericRefinementRegionSeg with null bitmap");
+      error(errSyntaxError, curStr->getPos(), "readGenericRefinementRegionSeg with null bitmap");
     }
   }
 
@@ -3251,7 +3251,7 @@ void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
   return;
 
  eofError:
-  error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
+  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
 }
 
 JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
@@ -3480,7 +3480,7 @@ void JBIG2Stream::readPageInfoSeg(Guint length) {
   return;
 
  eofError:
-  error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
+  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
 }
 
 void JBIG2Stream::readEndOfStripeSeg(Guint length) {
@@ -3562,7 +3562,7 @@ void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
   return;
 
  eofError:
-  error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
+  error(errSyntaxError, curStr->getPos(), "Unexpected EOF in JBIG2 stream");
 }
 
 void JBIG2Stream::readExtensionSeg(Guint length) {
diff --git a/poppler/JPEG2000Stream.cc b/poppler/JPEG2000Stream.cc
index a96fc10..bae7a84 100644
--- a/poppler/JPEG2000Stream.cc
+++ b/poppler/JPEG2000Stream.cc
@@ -113,11 +113,11 @@ void JPXStream::init()
 }
 
 static void libopenjpeg_error_callback(const char *msg, void * /*client_data*/) {
-  error(-1, "%s", msg);
+  error(errSyntaxError, -1, "{0:s}", msg);
 }
 
 static void libopenjpeg_warning_callback(const char *msg, void * /*client_data*/) {
-  error(-1, "%s", msg);
+  error(errSyntaxWarning, -1, "{0:s}", msg);
 }
 
 void JPXStream::init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT format)
@@ -159,13 +159,13 @@ void JPXStream::init2(unsigned char *buf, int bufLen, OPJ_CODEC_FORMAT format)
 
 error:
   if (format == CODEC_JP2) {
-    error(-1, "Did no succeed opening JPX Stream as JP2, trying as J2K.");
+    error(errSyntaxWarning, -1, "Did no succeed opening JPX Stream as JP2, trying as J2K.");
     init2(buf, bufLen, CODEC_J2K);
   } else if (format == CODEC_J2K) {
-    error(-1, "Did no succeed opening JPX Stream as J2K, trying as JPT.");
+    error(errSyntaxWarning, -1, "Did no succeed opening JPX Stream as J2K, trying as JPT.");
     init2(buf, bufLen, CODEC_JPT);
   } else {
-    error(-1, "Did no succeed opening JPX Stream.");
+    error(errSyntaxError, -1, "Did no succeed opening JPX Stream.");
   }
 }
 
diff --git a/poppler/JPXStream.cc b/poppler/JPXStream.cc
index 3b8c05d..724b4f5 100644
--- a/poppler/JPXStream.cc
+++ b/poppler/JPXStream.cc
@@ -590,7 +590,8 @@ GBool JPXStream::readBoxes() {
   // Acrobat allows it
   if (str->lookChar() == 0xff) {
     cover(7);
-    error(getPos(), "Naked JPEG 2000 codestream, missing JP2/JPX wrapper");
+    error(errSyntaxWarning, getPos(),
+	  "Naked JPEG 2000 codestream, missing JP2/JPX wrapper");
     readCodestream(0);
     nComps = img.nComps;
     bpc = (Guint *)gmallocn(nComps, sizeof(Guint));
@@ -621,11 +622,11 @@ GBool JPXStream::readBoxes() {
 	  !readUByte(&compression) ||
 	  !readUByte(&unknownColorspace) ||
 	  !readUByte(&ipr)) {
-	error(getPos(), "Unexpected EOF in JPX stream");
+	error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
 	return gFalse;
       }
       if (compression != 7) {
-	error(getPos(), "Unknown compression type in JPX stream");
+	error(errSyntaxError, getPos(), "Unknown compression type in JPX stream");
 	return gFalse;
       }
       bpc = (Guint *)gmallocn(nComps, sizeof(Guint));
@@ -637,16 +638,16 @@ GBool JPXStream::readBoxes() {
     case 0x62706363:		// bits per component
       cover(10);
       if (!haveImgHdr) {
-	error(getPos(), "Found bits per component box before image header box in JPX stream");
+	error(errSyntaxError, getPos(), "Found bits per component box before image header box in JPX stream");
 	return gFalse;
       }
       if (dataLen != nComps) {
-	error(getPos(), "Invalid bits per component box in JPX stream");
+	error(errSyntaxError, getPos(), "Invalid bits per component box in JPX stream");
 	return gFalse;
       }
       for (i = 0; i < nComps; ++i) {
 	if (!readUByte(&bpc[i])) {
-	  error(getPos(), "Unexpected EOF in JPX stream");
+	  error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
 	  return gFalse;
 	}
       }
@@ -661,7 +662,7 @@ GBool JPXStream::readBoxes() {
       cover(12);
       if (!readUWord(&palette.nEntries) ||
 	  !readUByte(&palette.nComps)) {
-	error(getPos(), "Unexpected EOF in JPX stream");
+	error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
 	return gFalse;
       }
       palette.bpc = (Guint *)gmallocn(palette.nComps, sizeof(Guint));
@@ -669,7 +670,7 @@ GBool JPXStream::readBoxes() {
           (int *)gmallocn(palette.nEntries * palette.nComps, sizeof(int));
       for (i = 0; i < palette.nComps; ++i) {
 	if (!readUByte(&palette.bpc[i])) {
-	  error(getPos(), "Unexpected EOF in JPX stream");
+	  error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
 	  return gFalse;
 	}
 	++palette.bpc[i];
@@ -679,7 +680,7 @@ GBool JPXStream::readBoxes() {
 	  if (!readNBytes(((palette.bpc[j] & 0x7f) + 7) >> 3,
 			  (palette.bpc[j] & 0x80) ? gTrue : gFalse,
 			  &palette.c[i * palette.nComps + j])) {
-	    error(getPos(), "Unexpected EOF in JPX stream");
+	    error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
 	    return gFalse;
 	  }
 	}
@@ -696,7 +697,7 @@ GBool JPXStream::readBoxes() {
 	if (!readUWord(&compMap.comp[i]) ||
 	    !readUByte(&compMap.type[i]) ||
 	    !readUByte(&compMap.pComp[i])) {
-	  error(getPos(), "Unexpected EOF in JPX stream");
+	  error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
 	  return gFalse;
 	}
       }
@@ -705,7 +706,7 @@ GBool JPXStream::readBoxes() {
     case 0x63646566:		// channel definition
       cover(14);
       if (!readUWord(&channelDefn.nChannels)) {
-	error(getPos(), "Unexpected EOF in JPX stream");
+	error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
 	return gFalse;
       }
       channelDefn.idx =
@@ -718,7 +719,7 @@ GBool JPXStream::readBoxes() {
 	if (!readUWord(&channelDefn.idx[i]) ||
 	    !readUWord(&channelDefn.type[i]) ||
 	    !readUWord(&channelDefn.assoc[i])) {
-	  error(getPos(), "Unexpected EOF in JPX stream");
+	  error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
 	  return gFalse;
 	}
       }
@@ -727,10 +728,10 @@ GBool JPXStream::readBoxes() {
     case 0x6A703263:		// contiguous codestream
       cover(15);
       if (!bpc) {
-	error(getPos(), "JPX stream is missing the image header box");
+	error(errSyntaxError, getPos(), "JPX stream is missing the image header box");
       }
       if (!haveCS) {
-	error(getPos(), "JPX stream has no supported color spec");
+	error(errSyntaxError, getPos(), "JPX stream has no supported color spec");
       }
       if (!readCodestream(dataLen)) {
 	return gFalse;
@@ -740,7 +741,7 @@ GBool JPXStream::readBoxes() {
       cover(16);
       for (i = 0; i < dataLen; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Unexpected EOF in JPX stream");
+	  error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
 	  return gFalse;
 	}
       }
@@ -871,7 +872,7 @@ GBool JPXStream::readColorSpecBox(Guint dataLen) {
   return gTrue;
 
  err:
-  error(getPos(), "Error in JPX color spec");
+  error(errSyntaxError, getPos(), "Error in JPX color spec");
   return gFalse;
 }
 
@@ -887,7 +888,7 @@ GBool JPXStream::readCodestream(Guint len) {
   haveSIZ = haveCOD = haveQCD = haveSOT = gFalse;
   do {
     if (!readMarkerHdr(&segType, &segLen)) {
-      error(getPos(), "Error in JPX codestream");
+      error(errSyntaxError, getPos(), "Error in JPX codestream");
       return gFalse;
     }
     switch (segType) {
@@ -907,11 +908,11 @@ GBool JPXStream::readCodestream(Guint len) {
 	  !readULong(&img.xTileOffset) ||
 	  !readULong(&img.yTileOffset) ||
 	  !readUWord(&img.nComps)) {
-	error(getPos(), "Error in JPX SIZ marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX SIZ marker segment");
 	return gFalse;
       }
       if (haveImgHdr && img.nComps != nComps) {
-	error(getPos(), "Different number of components in JPX SIZ marker segment");
+	error(errSyntaxError, getPos(), "Different number of components in JPX SIZ marker segment");
 	return gFalse;
       }
       img.nXTiles = (img.xSize - img.xTileOffset + img.xTileSize - 1)
@@ -921,7 +922,7 @@ GBool JPXStream::readCodestream(Guint len) {
       // check for overflow before allocating memory
       if (img.nXTiles <= 0 || img.nYTiles <= 0 ||
 	  img.nXTiles >= INT_MAX / img.nYTiles) {
-	error(getPos(), "Bad tile count in JPX SIZ marker segment");
+	error(errSyntaxError, getPos(), "Bad tile count in JPX SIZ marker segment");
 	return gFalse;
       }
       img.tiles = (JPXTile *)gmallocn(img.nXTiles * img.nYTiles,
@@ -940,7 +941,7 @@ GBool JPXStream::readCodestream(Guint len) {
 	if (!readUByte(&img.tiles[0].tileComps[comp].prec) ||
 	    !readUByte(&img.tiles[0].tileComps[comp].hSep) ||
 	    !readUByte(&img.tiles[0].tileComps[comp].vSep)) {
-	  error(getPos(), "Error in JPX SIZ marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX SIZ marker segment");
 	  return gFalse;
 	}
 	img.tiles[0].tileComps[comp].sgned =
@@ -964,7 +965,7 @@ GBool JPXStream::readCodestream(Guint len) {
 	  !readUByte(&img.tiles[0].tileComps[0].codeBlockH) ||
 	  !readUByte(&img.tiles[0].tileComps[0].codeBlockStyle) ||
 	  !readUByte(&img.tiles[0].tileComps[0].transform)) {
-	error(getPos(), "Error in JPX COD marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
 	return gFalse;
       }
       img.tiles[0].tileComps[0].codeBlockW += 2;
@@ -1003,7 +1004,7 @@ GBool JPXStream::readCodestream(Guint len) {
 	if (img.tiles[0].tileComps[0].style & 0x01) {
 	  cover(91);
 	  if (!readUByte(&precinctSize)) {
-	    error(getPos(), "Error in JPX COD marker segment");
+	    error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
 	    return gFalse;
 	  }
 	  img.tiles[0].tileComps[0].resLevels[r].precinctWidth =
@@ -1032,7 +1033,7 @@ GBool JPXStream::readCodestream(Guint len) {
     case 0x53:			// COC - coding style component
       cover(22);
       if (!haveCOD) {
-	error(getPos(), "JPX COC marker segment before COD segment");
+	error(errSyntaxError, getPos(), "JPX COC marker segment before COD segment");
 	return gFalse;
       }
       if ((img.nComps > 256 && !readUWord(&comp)) ||
@@ -1044,7 +1045,7 @@ GBool JPXStream::readCodestream(Guint len) {
 	  !readUByte(&img.tiles[0].tileComps[comp].codeBlockH) ||
 	  !readUByte(&img.tiles[0].tileComps[comp].codeBlockStyle) ||
 	  !readUByte(&img.tiles[0].tileComps[comp].transform)) {
-	error(getPos(), "Error in JPX COC marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX COC marker segment");
 	return gFalse;
       }
       img.tiles[0].tileComps[comp].style =
@@ -1078,7 +1079,7 @@ GBool JPXStream::readCodestream(Guint len) {
       for (r = 0; r <= img.tiles[0].tileComps[comp].nDecompLevels; ++r) {
 	if (img.tiles[0].tileComps[comp].style & 0x01) {
 	  if (!readUByte(&precinctSize)) {
-	    error(getPos(), "Error in JPX COD marker segment");
+	    error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
 	    return gFalse;
 	  }
 	  img.tiles[0].tileComps[comp].resLevels[r].precinctWidth =
@@ -1102,7 +1103,7 @@ GBool JPXStream::readCodestream(Guint len) {
     case 0x5c:			// QCD - quantization default
       cover(23);
       if (!readUByte(&img.tiles[0].tileComps[0].quantStyle)) {
-	error(getPos(), "Error in JPX QCD marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
 	return gFalse;
       }
       if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x00) {
@@ -1113,7 +1114,7 @@ GBool JPXStream::readCodestream(Guint len) {
 			       sizeof(Guint));
 	for (i = 0; i < img.tiles[0].tileComps[0].nQuantSteps; ++i) {
 	  if (!readUByte(&img.tiles[0].tileComps[0].quantSteps[i])) {
-	    error(getPos(), "Error in JPX QCD marker segment");
+	    error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
 	    return gFalse;
 	  }
 	}
@@ -1124,7 +1125,7 @@ GBool JPXStream::readCodestream(Guint len) {
 			       img.tiles[0].tileComps[0].nQuantSteps,
 			       sizeof(Guint));
 	if (!readUWord(&img.tiles[0].tileComps[0].quantSteps[0])) {
-	  error(getPos(), "Error in JPX QCD marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
 	  return gFalse;
 	}
       } else if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x02) {
@@ -1135,12 +1136,12 @@ GBool JPXStream::readCodestream(Guint len) {
 			       sizeof(Guint));
 	for (i = 0; i < img.tiles[0].tileComps[0].nQuantSteps; ++i) {
 	  if (!readUWord(&img.tiles[0].tileComps[0].quantSteps[i])) {
-	    error(getPos(), "Error in JPX QCD marker segment");
+	    error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
 	    return gFalse;
 	  }
 	}
       } else {
-	error(getPos(), "Error in JPX QCD marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
 	return gFalse;
       }
       for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
@@ -1166,14 +1167,14 @@ GBool JPXStream::readCodestream(Guint len) {
     case 0x5d:			// QCC - quantization component
       cover(24);
       if (!haveQCD) {
-	error(getPos(), "JPX QCC marker segment before QCD segment");
+	error(errSyntaxError, getPos(), "JPX QCC marker segment before QCD segment");
 	return gFalse;
       }
       if ((img.nComps > 256 && !readUWord(&comp)) ||
 	  (img.nComps <= 256 && !readUByte(&comp)) ||
 	  comp >= img.nComps ||
 	  !readUByte(&img.tiles[0].tileComps[comp].quantStyle)) {
-	error(getPos(), "Error in JPX QCC marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
 	return gFalse;
       }
       if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x00) {
@@ -1185,7 +1186,7 @@ GBool JPXStream::readCodestream(Guint len) {
 			       sizeof(Guint));
 	for (i = 0; i < img.tiles[0].tileComps[comp].nQuantSteps; ++i) {
 	  if (!readUByte(&img.tiles[0].tileComps[comp].quantSteps[i])) {
-	    error(getPos(), "Error in JPX QCC marker segment");
+	    error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
 	    return gFalse;
 	  }
 	}
@@ -1196,7 +1197,7 @@ GBool JPXStream::readCodestream(Guint len) {
 			       img.tiles[0].tileComps[comp].nQuantSteps,
 			       sizeof(Guint));
 	if (!readUWord(&img.tiles[0].tileComps[comp].quantSteps[0])) {
-	  error(getPos(), "Error in JPX QCC marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
 	  return gFalse;
 	}
       } else if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x02) {
@@ -1208,12 +1209,12 @@ GBool JPXStream::readCodestream(Guint len) {
 			       sizeof(Guint));
 	for (i = 0; i < img.tiles[0].tileComps[comp].nQuantSteps; ++i) {
 	  if (!readUWord(&img.tiles[0].tileComps[comp].quantSteps[i])) {
-	    error(getPos(), "Error in JPX QCD marker segment");
+	    error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
 	    return gFalse;
 	  }
 	}
       } else {
-	error(getPos(), "Error in JPX QCC marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
 	return gFalse;
       }
       for (i = 1; i < img.nXTiles * img.nYTiles; ++i) {
@@ -1237,7 +1238,7 @@ GBool JPXStream::readCodestream(Guint len) {
       fprintf(stderr, "RGN\n");
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Error in JPX PPM marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX PPM marker segment");
 	  return gFalse;
 	}
       }
@@ -1247,7 +1248,7 @@ GBool JPXStream::readCodestream(Guint len) {
 	  comp >= img.nComps ||
 	  !readUByte(&compInfo[comp].defROI.style) ||
 	  !readUByte(&compInfo[comp].defROI.shift)) {
-	error(getPos(), "Error in JPX RGN marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX RGN marker segment");
 	return gFalse;
       }
 #endif
@@ -1258,7 +1259,7 @@ GBool JPXStream::readCodestream(Guint len) {
       fprintf(stderr, "POC\n");
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Error in JPX PPM marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX PPM marker segment");
 	  return gFalse;
 	}
       }
@@ -1274,7 +1275,7 @@ GBool JPXStream::readCodestream(Guint len) {
 	    !(img.nComps > 256 && readUWord(&progs[i].endComp)) ||
 	    !(img.nComps <= 256 && readUByte(&progs[i].endComp)) ||
 	    !readUByte(&progs[i].progOrder)) {
-	  error(getPos(), "Error in JPX POC marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX POC marker segment");
 	  return gFalse;
 	}
       }
@@ -1286,7 +1287,7 @@ GBool JPXStream::readCodestream(Guint len) {
       fprintf(stderr, "PPM\n");
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Error in JPX PPM marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX PPM marker segment");
 	  return gFalse;
 	}
       }
@@ -1297,7 +1298,7 @@ GBool JPXStream::readCodestream(Guint len) {
       cover(28);
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Error in JPX TLM marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX TLM marker segment");
 	  return gFalse;
 	}
       }
@@ -1307,7 +1308,7 @@ GBool JPXStream::readCodestream(Guint len) {
       cover(29);
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Error in JPX PLM marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX PLM marker segment");
 	  return gFalse;
 	}
       }
@@ -1317,7 +1318,7 @@ GBool JPXStream::readCodestream(Guint len) {
       cover(30);
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Error in JPX CRG marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX CRG marker segment");
 	  return gFalse;
 	}
       }
@@ -1327,7 +1328,7 @@ GBool JPXStream::readCodestream(Guint len) {
       cover(31);
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Error in JPX COM marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX COM marker segment");
 	  return gFalse;
 	}
       }
@@ -1338,7 +1339,8 @@ GBool JPXStream::readCodestream(Guint len) {
       break;
     default:
       cover(33);
-      error(getPos(), "Unknown marker segment %02x in JPX stream", segType);
+      error(errSyntaxError, getPos(),
+	    "Unknown marker segment {0:02x} in JPX stream", segType);
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
 	  break;
@@ -1349,15 +1351,15 @@ GBool JPXStream::readCodestream(Guint len) {
   } while (!haveSOT);
 
   if (!haveSIZ) {
-    error(getPos(), "Missing SIZ marker segment in JPX stream");
+    error(errSyntaxError, getPos(), "Missing SIZ marker segment in JPX stream");
     return gFalse;
   }
   if (!haveCOD) {
-    error(getPos(), "Missing COD marker segment in JPX stream");
+    error(errSyntaxError, getPos(), "Missing COD marker segment in JPX stream");
     return gFalse;
   }
   if (!haveQCD) {
-    error(getPos(), "Missing QCD marker segment in JPX stream");
+    error(errSyntaxError, getPos(), "Missing QCD marker segment in JPX stream");
     return gFalse;
   }
 
@@ -1367,7 +1369,7 @@ GBool JPXStream::readCodestream(Guint len) {
       return gFalse;
     }
     if (!readMarkerHdr(&segType, &segLen)) {
-      error(getPos(), "Error in JPX codestream");
+      error(errSyntaxError, getPos(), "Error in JPX codestream");
       return gFalse;
     }
     if (segType != 0x90) {	// SOT - start of tile
@@ -1376,7 +1378,7 @@ GBool JPXStream::readCodestream(Guint len) {
   }
 
   if (segType != 0xd9) {	// EOC - end of codestream
-    error(getPos(), "Missing EOC marker in JPX codestream");
+    error(errSyntaxError, getPos(), "Missing EOC marker in JPX codestream");
     return gFalse;
   }
 
@@ -1417,12 +1419,12 @@ GBool JPXStream::readTilePart() {
       !readULong(&tilePartLen) ||
       !readUByte(&tilePartIdx) ||
       !readUByte(&nTileParts)) {
-    error(getPos(), "Error in JPX SOT marker segment");
+    error(errSyntaxError, getPos(), "Error in JPX SOT marker segment");
     return gFalse;
   }
 
   if (tileIdx >= img.nXTiles * img.nYTiles) {
-    error(getPos(), "Weird tile index in JPX stream");
+    error(errSyntaxError, getPos(), "Weird tile index in JPX stream");
     return gFalse;
   }
 
@@ -1432,7 +1434,7 @@ GBool JPXStream::readTilePart() {
   haveSOD = gFalse;
   do {
     if (!readMarkerHdr(&segType, &segLen)) {
-      error(getPos(), "Error in JPX tile-part codestream");
+      error(errSyntaxError, getPos(), "Error in JPX tile-part codestream");
       return gFalse;
     }
     tilePartLen -= 2 + segLen;
@@ -1448,7 +1450,7 @@ GBool JPXStream::readTilePart() {
 	  !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockH) ||
 	  !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockStyle) ||
 	  !readUByte(&img.tiles[tileIdx].tileComps[0].transform)) {
-	error(getPos(), "Error in JPX COD marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
 	return gFalse;
       }
       img.tiles[tileIdx].tileComps[0].codeBlockW += 2;
@@ -1482,7 +1484,7 @@ GBool JPXStream::readTilePart() {
       for (r = 0; r <= img.tiles[tileIdx].tileComps[0].nDecompLevels; ++r) {
 	if (img.tiles[tileIdx].tileComps[0].style & 0x01) {
 	  if (!readUByte(&precinctSize)) {
-	    error(getPos(), "Error in JPX COD marker segment");
+	    error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
 	    return gFalse;
 	  }
 	  img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth =
@@ -1516,7 +1518,7 @@ GBool JPXStream::readTilePart() {
 	  !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockH) ||
 	  !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockStyle) ||
 	  !readUByte(&img.tiles[tileIdx].tileComps[comp].transform)) {
-	error(getPos(), "Error in JPX COC marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX COC marker segment");
 	return gFalse;
       }
       img.tiles[tileIdx].tileComps[comp].style =
@@ -1534,7 +1536,7 @@ GBool JPXStream::readTilePart() {
       for (r = 0; r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels; ++r) {
 	if (img.tiles[tileIdx].tileComps[comp].style & 0x01) {
 	  if (!readUByte(&precinctSize)) {
-	    error(getPos(), "Error in JPX COD marker segment");
+	    error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
 	    return gFalse;
 	  }
 	  img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth =
@@ -1550,7 +1552,7 @@ GBool JPXStream::readTilePart() {
     case 0x5c:			// QCD - quantization default
       cover(36);
       if (!readUByte(&img.tiles[tileIdx].tileComps[0].quantStyle)) {
-	error(getPos(), "Error in JPX QCD marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
 	return gFalse;
       }
       if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x00) {
@@ -1562,7 +1564,7 @@ GBool JPXStream::readTilePart() {
 			       sizeof(Guint));
 	for (i = 0; i < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++i) {
 	  if (!readUByte(&img.tiles[tileIdx].tileComps[0].quantSteps[i])) {
-	    error(getPos(), "Error in JPX QCD marker segment");
+	    error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
 	    return gFalse;
 	  }
 	}
@@ -1573,7 +1575,7 @@ GBool JPXStream::readTilePart() {
 			       img.tiles[tileIdx].tileComps[0].nQuantSteps,
 			       sizeof(Guint));
 	if (!readUWord(&img.tiles[tileIdx].tileComps[0].quantSteps[0])) {
-	  error(getPos(), "Error in JPX QCD marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
 	  return gFalse;
 	}
       } else if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x02) {
@@ -1584,12 +1586,12 @@ GBool JPXStream::readTilePart() {
 			       sizeof(Guint));
 	for (i = 0; i < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++i) {
 	  if (!readUWord(&img.tiles[tileIdx].tileComps[0].quantSteps[i])) {
-	    error(getPos(), "Error in JPX QCD marker segment");
+	    error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
 	    return gFalse;
 	  }
 	}
       } else {
-	error(getPos(), "Error in JPX QCD marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
 	return gFalse;
       }
       for (comp = 1; comp < img.nComps; ++comp) {
@@ -1613,7 +1615,7 @@ GBool JPXStream::readTilePart() {
 	  (img.nComps <= 256 && !readUByte(&comp)) ||
 	  comp >= img.nComps ||
 	  !readUByte(&img.tiles[tileIdx].tileComps[comp].quantStyle)) {
-	error(getPos(), "Error in JPX QCC marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
 	return gFalse;
       }
       if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f) == 0x00) {
@@ -1625,7 +1627,7 @@ GBool JPXStream::readTilePart() {
 			       sizeof(Guint));
 	for (i = 0; i < img.tiles[tileIdx].tileComps[comp].nQuantSteps; ++i) {
 	  if (!readUByte(&img.tiles[tileIdx].tileComps[comp].quantSteps[i])) {
-	    error(getPos(), "Error in JPX QCC marker segment");
+	    error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
 	    return gFalse;
 	  }
 	}
@@ -1637,7 +1639,7 @@ GBool JPXStream::readTilePart() {
 			       img.tiles[tileIdx].tileComps[comp].nQuantSteps,
 			       sizeof(Guint));
 	if (!readUWord(&img.tiles[tileIdx].tileComps[comp].quantSteps[0])) {
-	  error(getPos(), "Error in JPX QCC marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
 	  return gFalse;
 	}
       } else if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f)
@@ -1650,12 +1652,12 @@ GBool JPXStream::readTilePart() {
 			       sizeof(Guint));
 	for (i = 0; i < img.tiles[tileIdx].tileComps[comp].nQuantSteps; ++i) {
 	  if (!readUWord(&img.tiles[tileIdx].tileComps[comp].quantSteps[i])) {
-	    error(getPos(), "Error in JPX QCD marker segment");
+	    error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
 	    return gFalse;
 	  }
 	}
       } else {
-	error(getPos(), "Error in JPX QCC marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
 	return gFalse;
       }
       break;
@@ -1665,7 +1667,7 @@ GBool JPXStream::readTilePart() {
       fprintf(stderr, "RGN\n");
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Error in JPX PPM marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX PPM marker segment");
 	  return gFalse;
 	}
       }
@@ -1675,7 +1677,7 @@ GBool JPXStream::readTilePart() {
 	  comp >= img.nComps ||
 	  !readUByte(&compInfo[comp].roi.style) ||
 	  !readUByte(&compInfo[comp].roi.shift)) {
-	error(getPos(), "Error in JPX RGN marker segment");
+	error(errSyntaxError, getPos(), "Error in JPX RGN marker segment");
 	return gFalse;
       }
 #endif
@@ -1686,7 +1688,7 @@ GBool JPXStream::readTilePart() {
       fprintf(stderr, "POC\n");
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Error in JPX PPM marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX PPM marker segment");
 	  return gFalse;
 	}
       }
@@ -1702,7 +1704,7 @@ GBool JPXStream::readTilePart() {
 	    !(img.nComps > 256 && readUWord(&tileProgs[i].endComp)) ||
 	    !(img.nComps <= 256 && readUByte(&tileProgs[i].endComp)) ||
 	    !readUByte(&tileProgs[i].progOrder)) {
-	  error(getPos(), "Error in JPX POC marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX POC marker segment");
 	  return gFalse;
 	}
       }
@@ -1714,7 +1716,7 @@ GBool JPXStream::readTilePart() {
       fprintf(stderr, "PPT\n");
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Error in JPX PPT marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX PPT marker segment");
 	  return gFalse;
 	}
       }
@@ -1724,7 +1726,7 @@ GBool JPXStream::readTilePart() {
       cover(41);
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Error in JPX PLT marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX PLT marker segment");
 	  return gFalse;
 	}
       }
@@ -1734,7 +1736,7 @@ GBool JPXStream::readTilePart() {
       cover(42);
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
-	  error(getPos(), "Error in JPX COM marker segment");
+	  error(errSyntaxError, getPos(), "Error in JPX COM marker segment");
 	  return gFalse;
 	}
       }
@@ -1745,8 +1747,9 @@ GBool JPXStream::readTilePart() {
       break;
     default:
       cover(44);
-      error(getPos(), "Unknown marker segment %02x in JPX tile-part stream",
-	    segType);
+      error(errSyntaxError, getPos(),
+	    "Unknown marker segment {0:02x} in JPX tile-part stream",
+ 	    segType);
       for (i = 0; i < segLen - 2; ++i) {
 	if (str->getChar() == EOF) {
 	  break;
@@ -2219,7 +2222,7 @@ GBool JPXStream::readTilePartData(Guint tileIdx,
   return gTrue;
 
  err:
-  error(getPos(), "Error in JPX stream");
+  error(errSyntaxError, getPos(), "Error in JPX stream");
   return gFalse;
 }
 
@@ -3016,7 +3019,8 @@ GBool JPXStream::readBoxHdr(Guint *boxType, Guint *boxLen, Guint *dataLen) {
       return gFalse;
     }
     if (lenH) {
-      error(getPos(), "JPX stream contains a box larger than 2^32 bytes");
+      error(errSyntaxError, getPos(),
+	    "JPX stream contains a box larger than 2^32 bytes");
       return gFalse;
     }
     *boxLen = len;
diff --git a/poppler/Lexer.cc b/poppler/Lexer.cc
index 6250d40..9864244 100644
--- a/poppler/Lexer.cc
+++ b/poppler/Lexer.cc
@@ -252,7 +252,7 @@ Object *Lexer::getObj(Object *obj, int objNum) {
       if (c == '-') {
 	// ignore minus signs in the middle of numbers to match
 	// Adobe's behavior
-	error(getPos(), "Badly formatted number");
+	error(errSyntaxWarning, getPos(), "Badly formatted number");
 	getChar();
 	continue;
       }
@@ -285,7 +285,7 @@ Object *Lexer::getObj(Object *obj, int objNum) {
       case '\r':
       case '\n':
 #endif
-	error(getPos(), "Unterminated string");
+	error(errSyntaxError, getPos(), "Unterminated string");
 	done = gTrue;
 	break;
 
@@ -347,7 +347,7 @@ Object *Lexer::getObj(Object *obj, int objNum) {
 	case '\n':
 	  break;
 	case EOF:
-	  error(getPos(), "Unterminated string");
+	  error(errSyntaxError, getPos(), "Unterminated string");
 	  done = gTrue;
 	  break;
 	default:
@@ -376,7 +376,7 @@ Object *Lexer::getObj(Object *obj, int objNum) {
 	    int newObjNum = xref->getNumEntry(curStr.streamGetPos());
 	    if (newObjNum != objNum)
 	    {
-	      error(getPos(), "Unterminated string");
+	      error(errSyntaxError, getPos(), "Unterminated string");
 	      done = gTrue;
 	      delete s;
 	      n = -2;
@@ -426,20 +426,20 @@ Object *Lexer::getObj(Object *obj, int objNum) {
 	} else if (c2 >= 'a' && c2 <= 'f') {
 	  c += c2 - 'a' + 10;
 	} else {
-	  error(getPos(), "Illegal digit in hex char in name");
+	  error(errSyntaxError, getPos(), "Illegal digit in hex char in name");
 	}
       }
      notEscChar:
       if (n == tokBufSize) {
 	if (!s)
 	{
-	  error(getPos(), "Warning: name token is longer than what the specification says it can be");
+	  error(errSyntaxError, getPos(), "Warning: name token is longer than what the specification says it can be");
 	  s = new GooString(tokBuf, tokBufSize);
 	}
 	else
 	{
 	  // the spec says 127 is the maximum, we are already at 256 so bail out
-	  error(getPos(), "Name token too long");
+	  error(errSyntaxError, getPos(), "Name token too long");
 	  break;
 	}
 	p = tokBuf;
@@ -486,7 +486,7 @@ Object *Lexer::getObj(Object *obj, int objNum) {
 	if (c == '>') {
 	  break;
 	} else if (c == EOF) {
-	  error(getPos(), "Unterminated hex string");
+	  error(errSyntaxError, getPos(), "Unterminated hex string");
 	  break;
 	} else if (specialChars[c] != 1) {
 	  c2 = c2 << 4;
@@ -497,7 +497,7 @@ Object *Lexer::getObj(Object *obj, int objNum) {
 	  else if (c >= 'a' && c <= 'f')
 	    c2 += c - 'a' + 10;
 	  else
-	    error(getPos(), "Illegal character <%02x> in hex string", c);
+	    error(errSyntaxError, getPos(), "Illegal character <{0:02x}> in hex string", c);
 	  if (++m == 2) {
 	    if (n == tokBufSize) {
 	      if (!s)
@@ -533,7 +533,7 @@ Object *Lexer::getObj(Object *obj, int objNum) {
       tokBuf[2] = '\0';
       obj->initCmd(tokBuf);
     } else {
-      error(getPos(), "Illegal character '>'");
+      error(errSyntaxError, getPos(), "Illegal character '>'");
       obj->initError();
     }
     break;
@@ -542,7 +542,7 @@ Object *Lexer::getObj(Object *obj, int objNum) {
   case ')':
   case '{':
   case '}':
-    error(getPos(), "Illegal character '%c'", c);
+    error(errSyntaxError, getPos(), "Illegal character '{0:c}'", c);
     obj->initError();
     break;
 
@@ -554,7 +554,7 @@ Object *Lexer::getObj(Object *obj, int objNum) {
     while ((c = lookChar()) != EOF && !specialChars[c]) {
       getChar();
       if (++n == tokBufSize) {
-	error(getPos(), "Command token too long");
+	error(errSyntaxError, getPos(), "Command token too long");
 	break;
       }
       *p++ = c;
diff --git a/poppler/Linearization.cc b/poppler/Linearization.cc
index 73dc5ad..7b8f1e0 100644
--- a/poppler/Linearization.cc
+++ b/poppler/Linearization.cc
@@ -60,7 +60,7 @@ Guint Linearization::getLength()
       length > 0) {
     return length;
   } else {
-    error(-1, "Length in linearization table is invalid");
+    error(errSyntaxWarning, -1, "Length in linearization table is invalid");
     return 0;
   }
 }
@@ -77,7 +77,7 @@ Guint Linearization::getHintsOffset()
       obj2.getInt() > 0) {
     hintsOffset = obj2.getInt();
   } else {
-    error(-1, "Hints table offset in linearization table is invalid");
+    error(errSyntaxWarning, -1, "Hints table offset in linearization table is invalid");
     hintsOffset = 0;
   }
   obj2.free();
@@ -98,7 +98,7 @@ Guint Linearization::getHintsLength()
       obj2.getInt() > 0) {
     hintsLength = obj2.getInt();
   } else {
-    error(-1, "Hints table length in linearization table is invalid");
+    error(errSyntaxWarning, -1, "Hints table length in linearization table is invalid");
     hintsLength = 0;
   }
   obj2.free();
@@ -119,7 +119,7 @@ Guint Linearization::getHintsOffset2()
         obj2.getInt() > 0) {
       hintsOffset2 = obj2.getInt();
     } else {
-      error(-1, "Second hints table offset in linearization table is invalid");
+      error(errSyntaxWarning, -1, "Second hints table offset in linearization table is invalid");
       hintsOffset2 = 0;
     }
   }
@@ -141,7 +141,7 @@ Guint Linearization::getHintsLength2()
         obj2.getInt() > 0) {
       hintsLength2 = obj2.getInt();
     } else {
-      error(-1, "Second hints table length in linearization table is invalid");
+      error(errSyntaxWarning, -1, "Second hints table length in linearization table is invalid");
       hintsLength2 = 0;
     }
   }
@@ -159,7 +159,7 @@ int Linearization::getObjectNumberFirst()
       objectNumberFirst > 0) {
     return objectNumberFirst;
   } else {
-    error(-1, "Object number of first page in linearization table is invalid");
+    error(errSyntaxWarning, -1, "Object number of first page in linearization table is invalid");
     return 0;
   }
 }
@@ -172,7 +172,7 @@ Guint Linearization::getEndFirst()
       pageEndFirst > 0) {
     return pageEndFirst;
   } else {
-    error(-1, "First page end offset in linearization table is invalid");
+    error(errSyntaxWarning, -1, "First page end offset in linearization table is invalid");
     return 0;
   }
 }
@@ -185,7 +185,7 @@ int Linearization::getNumPages()
       numPages > 0) {
     return numPages;
   } else {
-    error(-1, "Page count in linearization table is invalid");
+    error(errSyntaxWarning, -1, "Page count in linearization table is invalid");
     return 0;
   }
 }
@@ -198,7 +198,7 @@ Guint Linearization::getMainXRefEntriesOffset()
       mainXRefEntriesOffset > 0) {
     return mainXRefEntriesOffset;
   } else {
-    error(-1, "Main Xref offset in linearization table is invalid");
+    error(errSyntaxWarning, -1, "Main Xref offset in linearization table is invalid");
     return 0;
   }
 }
@@ -212,7 +212,7 @@ int Linearization::getPageFirst()
   }
 
   if (pageFirst < 0) {
-    error(-1, "First page in linearization table is invalid");
+    error(errSyntaxWarning, -1, "First page in linearization table is invalid");
     return 0;
   }
 
diff --git a/poppler/Link.cc b/poppler/Link.cc
index 971accf..7a59d47 100644
--- a/poppler/Link.cc
+++ b/poppler/Link.cc
@@ -66,7 +66,7 @@ LinkAction *LinkAction::parseAction(Object *obj, GooString *baseURI) {
   Object obj2, obj3, obj4;
 
   if (!obj->isDict()) {
-      error(-1, "parseAction: Bad annotation action for URI '%s'",
+      error(errSyntaxWarning, -1, "parseAction: Bad annotation action for URI '{0:s}'",
             baseURI ? baseURI->getCString() : "NULL");
       return NULL;
   }
@@ -131,7 +131,7 @@ LinkAction *LinkAction::parseAction(Object *obj, GooString *baseURI) {
 
   // action is missing or wrong type
   } else {
-    error(-1, "parseAction: Unknown annotation action object: URI = '%s'",
+    error(errSyntaxWarning, -1, "parseAction: Unknown annotation action object: URI = '{0:s}'",
           baseURI ? baseURI->getCString() : "NULL");
     action = NULL;
   }
@@ -159,7 +159,7 @@ LinkDest::LinkDest(Array *a) {
 
   // get page
   if (a->getLength() < 2) {
-    error(-1, "Annotation destination array is too short");
+    error(errSyntaxWarning, -1, "Annotation destination array is too short");
     return;
   }
   a->getNF(0, &obj1);
@@ -171,7 +171,7 @@ LinkDest::LinkDest(Array *a) {
     pageRef.gen = obj1.getRefGen();
     pageIsRef = gTrue;
   } else {
-    error(-1, "Bad annotation destination");
+    error(errSyntaxWarning, -1, "Bad annotation destination");
     goto err2;
   }
   obj1.free();
@@ -192,7 +192,7 @@ LinkDest::LinkDest(Array *a) {
 	changeLeft = gTrue;
 	left = obj2.getNum();
       } else {
-	error(-1, "Bad annotation destination position");
+	error(errSyntaxWarning, -1, "Bad annotation destination position");
 	goto err1;
       }
       obj2.free();
@@ -207,7 +207,7 @@ LinkDest::LinkDest(Array *a) {
 	changeTop = gTrue;
 	top = obj2.getNum();
       } else {
-	error(-1, "Bad annotation destination position");
+	error(errSyntaxWarning, -1, "Bad annotation destination position");
 	goto err1;
       }
       obj2.free();
@@ -222,7 +222,7 @@ LinkDest::LinkDest(Array *a) {
 	changeZoom = gTrue;
 	zoom = obj2.getNum();
       } else {
-	error(-1, "Bad annotation destination position");
+	error(errSyntaxWarning, -1, "Bad annotation destination position");
 	goto err1;
       }
       obj2.free();
@@ -231,7 +231,7 @@ LinkDest::LinkDest(Array *a) {
   // Fit link
   } else if (obj1.isName("Fit")) {
     if (a->getLength() < 2) {
-      error(-1, "Annotation destination array is too short");
+      error(errSyntaxWarning, -1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFit;
@@ -239,7 +239,7 @@ LinkDest::LinkDest(Array *a) {
   // FitH link
   } else if (obj1.isName("FitH")) {
     if (a->getLength() < 3) {
-      error(-1, "Annotation destination array is too short");
+      error(errSyntaxWarning, -1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFitH;
@@ -250,7 +250,7 @@ LinkDest::LinkDest(Array *a) {
       changeTop = gTrue;
       top = obj2.getNum();
     } else {
-      error(-1, "Bad annotation destination position");
+      error(errSyntaxWarning, -1, "Bad annotation destination position");
       kind = destFit;
     }
     obj2.free();
@@ -258,7 +258,7 @@ LinkDest::LinkDest(Array *a) {
   // FitV link
   } else if (obj1.isName("FitV")) {
     if (a->getLength() < 3) {
-      error(-1, "Annotation destination array is too short");
+      error(errSyntaxWarning, -1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFitV;
@@ -269,7 +269,7 @@ LinkDest::LinkDest(Array *a) {
       changeLeft = gTrue;
       left = obj2.getNum();
     } else {
-      error(-1, "Bad annotation destination position");
+      error(errSyntaxWarning, -1, "Bad annotation destination position");
       kind = destFit;
     }
     obj2.free();
@@ -277,30 +277,30 @@ LinkDest::LinkDest(Array *a) {
   // FitR link
   } else if (obj1.isName("FitR")) {
     if (a->getLength() < 6) {
-      error(-1, "Annotation destination array is too short");
+      error(errSyntaxWarning, -1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFitR;
     if (!a->get(2, &obj2)->isNum()) {
-      error(-1, "Bad annotation destination position");
+      error(errSyntaxWarning, -1, "Bad annotation destination position");
       kind = destFit;
     }
     left = obj2.getNum();
     obj2.free();
     if (!a->get(3, &obj2)->isNum()) {
-      error(-1, "Bad annotation destination position");
+      error(errSyntaxWarning, -1, "Bad annotation destination position");
       kind = destFit;
     }
     bottom = obj2.getNum();
     obj2.free();
     if (!a->get(4, &obj2)->isNum()) {
-      error(-1, "Bad annotation destination position");
+      error(errSyntaxWarning, -1, "Bad annotation destination position");
       kind = destFit;
     }
     right = obj2.getNum();
     obj2.free();
     if (!a->get(5, &obj2)->isNum()) {
-      error(-1, "Bad annotation destination position");
+      error(errSyntaxWarning, -1, "Bad annotation destination position");
       kind = destFit;
     }
     top = obj2.getNum();
@@ -309,7 +309,7 @@ LinkDest::LinkDest(Array *a) {
   // FitB link
   } else if (obj1.isName("FitB")) {
     if (a->getLength() < 2) {
-      error(-1, "Annotation destination array is too short");
+      error(errSyntaxWarning, -1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFitB;
@@ -317,7 +317,7 @@ LinkDest::LinkDest(Array *a) {
   // FitBH link
   } else if (obj1.isName("FitBH")) {
     if (a->getLength() < 3) {
-      error(-1, "Annotation destination array is too short");
+      error(errSyntaxWarning, -1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFitBH;
@@ -328,7 +328,7 @@ LinkDest::LinkDest(Array *a) {
       changeTop = gTrue;
       top = obj2.getNum();
     } else {
-      error(-1, "Bad annotation destination position");
+      error(errSyntaxWarning, -1, "Bad annotation destination position");
       kind = destFit;
     }
     obj2.free();
@@ -336,7 +336,7 @@ LinkDest::LinkDest(Array *a) {
   // FitBV link
   } else if (obj1.isName("FitBV")) {
     if (a->getLength() < 3) {
-      error(-1, "Annotation destination array is too short");
+      error(errSyntaxWarning, -1, "Annotation destination array is too short");
       goto err2;
     }
     kind = destFitBV;
@@ -347,14 +347,14 @@ LinkDest::LinkDest(Array *a) {
       changeLeft = gTrue;
       left = obj2.getNum();
     } else {
-      error(-1, "Bad annotation destination position");
+      error(errSyntaxWarning, -1, "Bad annotation destination position");
       kind = destFit;
     }
     obj2.free();
 
   // unknown link kind
   } else {
-    error(-1, "Unknown annotation destination type");
+    error(errSyntaxWarning, -1, "Unknown annotation destination type");
     goto err2;
   }
 
@@ -410,7 +410,7 @@ LinkGoTo::LinkGoTo(Object *destObj) {
 
   // error
   } else {
-    error(-1, "Illegal annotation destination");
+    error(errSyntaxWarning, -1, "Illegal annotation destination");
   }
 }
 
@@ -453,7 +453,7 @@ LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) {
 
   // error
   } else {
-    error(-1, "Illegal annotation destination");
+    error(errSyntaxWarning, -1, "Illegal annotation destination");
   }
 }
 
@@ -498,7 +498,7 @@ LinkLaunch::LinkLaunch(Object *actionObj) {
 	}
 	obj2.free();
       } else {
-	error(-1, "Bad launch-type link action");
+	error(errSyntaxWarning, -1, "Bad launch-type link action");
       }
 #else
       //~ This hasn't been defined by Adobe yet, so assume it looks
@@ -515,7 +515,7 @@ LinkLaunch::LinkLaunch(Object *actionObj) {
 	}
 	obj2.free();
       } else {
-	error(-1, "Bad launch-type link action");
+	error(errSyntaxWarning, -1, "Bad launch-type link action");
       }
 #endif
     }
@@ -565,7 +565,7 @@ LinkURI::LinkURI(Object *uriObj, GooString *baseURI) {
       uri = uri2;
     }
   } else {
-    error(-1, "Illegal URI-type link");
+    error(errSyntaxWarning, -1, "Illegal URI-type link");
   }
 }
 
@@ -611,7 +611,8 @@ LinkMovie::LinkMovie(Object *obj) {
   tmp.free();
 
   if ((annotTitle == NULL) && (annotRef.num == -1)) {
-    error(-1, "Movie action is missing both the Annot and T keys");
+    error(errSyntaxError, -1,
+	  "Movie action is missing both the Annot and T keys");
   }
 
   if (obj->dictLookup("Operation", &tmp)->isName()) {
@@ -707,7 +708,7 @@ LinkRendition::LinkRendition(Object *obj) {
 	js = new GooString();
 	stream->fillGooString(js);
       } else {
-        error(-1, "Invalid Rendition Action: JS not string or stream");
+        error(errSyntaxWarning, -1, "Invalid Rendition Action: JS not string or stream");
       }
     }
     tmp.free();
@@ -715,7 +716,7 @@ LinkRendition::LinkRendition(Object *obj) {
     if (obj->dictLookup("OP", &tmp)->isInt()) {
       operation = tmp.getInt();
       if (!js && (operation < 0 || operation > 4)) {
-        error (-1, "Invalid Rendition Action: unrecognized operation valued: %d", operation);
+        error(errSyntaxWarning, -1, "Invalid Rendition Action: unrecognized operation valued: {0:d}", operation);
       } else {
         Object obj1;
 
@@ -723,17 +724,17 @@ LinkRendition::LinkRendition(Object *obj) {
         if (obj->dictLookup("R", &renditionObj)->isDict()) {
           media = new MediaRendition(&renditionObj);
 	} else if (operation == 0 || operation == 4) {
-          error (-1, "Invalid Rendition Action: no R field with op = %d", operation);
+          error(errSyntaxWarning, -1, "Invalid Rendition Action: no R field with op = {0:d}", operation);
 	  renditionObj.free();
 	}
 
 	if (!obj->dictLookupNF("AN", &screenRef)->isRef() && operation >= 0 && operation <= 4) {
-	  error (-1, "Invalid Rendition Action: no AN field with op = %d", operation);
+	  error(errSyntaxWarning, -1, "Invalid Rendition Action: no AN field with op = {0:d}", operation);
 	  screenRef.free();
 	}
       }
     } else if (!js) {
-      error(-1, "Invalid Rendition action: no OP or JS field defined");
+      error(errSyntaxWarning, -1, "Invalid Rendition action: no OP or JS field defined");
     }
     tmp.free();
   }
@@ -803,7 +804,7 @@ LinkOCGState::LinkOCGState(Object *obj) {
 	} else if (!strcmp (name, "Toggle")) {
 	  stList->st = Toggle;
 	} else {
-	  error (-1, "Invalid name '%s' in OCG Action state array", name);
+	  error(errSyntaxWarning, -1, "Invalid name '{0:s}' in OCG Action state array", name);
 	  delete stList;
 	  stList = NULL;
 	}
@@ -815,10 +816,10 @@ LinkOCGState::LinkOCGState(Object *obj) {
 	  item->gen = ocgRef.gen;
 	  stList->list->append(item);
 	} else {
-	  error (-1, "Invalid OCG Action State array, expected name instead of ref");
+	  error(errSyntaxWarning, -1, "Invalid OCG Action State array, expected name instead of ref");
 	}
       } else {
-        error (-1, "Invalid item in OCG Action State array");
+        error(errSyntaxWarning, -1, "Invalid item in OCG Action State array");
       }
       obj2.free();
     }
@@ -826,7 +827,7 @@ LinkOCGState::LinkOCGState(Object *obj) {
     if (stList)
       stateList->append(stList);
   } else {
-    error (-1, "Invalid OCGState action");
+    error(errSyntaxWarning, -1, "Invalid OCGState action");
     delete stateList;
     stateList = NULL;
   }
diff --git a/poppler/Movie.cc b/poppler/Movie.cc
index 3e764ac..f68b6ad 100644
--- a/poppler/Movie.cc
+++ b/poppler/Movie.cc
@@ -194,7 +194,7 @@ void Movie::parseMovie (Object *movieDict) {
     fileName = obj2.getString()->copy();
     obj2.free();
   } else {
-    error (-1, "Invalid Movie");
+    error (errSyntaxError, -1, "Invalid Movie");
     ok = gFalse;
     obj1.free();
     return;
diff --git a/poppler/Object.h b/poppler/Object.h
index 95c7afd..1b58037 100644
--- a/poppler/Object.h
+++ b/poppler/Object.h
@@ -41,15 +41,15 @@
 
 #define OBJECT_TYPE_CHECK(wanted_type) \
     if (unlikely(type != wanted_type)) { \
-        error(0, (char *) "Call to Object where the object was type %d, " \
-                 "not the expected type %d", type, wanted_type); \
+        error(errInternal, 0, (char *) "Call to Object where the object was type {0:d}, " \
+                 "not the expected type {1:d}", type, wanted_type); \
         abort(); \
     }
 
 #define OBJECT_2TYPES_CHECK(wanted_type1, wanted_type2) \
     if (unlikely(type != wanted_type1) && unlikely(type != wanted_type2)) { \
-        error(0, (char *) "Call to Object where the object was type %d, " \
-                 "not the expected type %d or %d", type, wanted_type1, wanted_type2); \
+        error(errInternal, 0, (char *) "Call to Object where the object was type {0:d}, " \
+                 "not the expected type {1:d} or {2:d}", type, wanted_type1, wanted_type2); \
         abort(); \
     }
 
diff --git a/poppler/OptionalContent.cc b/poppler/OptionalContent.cc
index c8b5c97..b5e19eb 100644
--- a/poppler/OptionalContent.cc
+++ b/poppler/OptionalContent.cc
@@ -37,7 +37,7 @@ OCGs::OCGs(Object *ocgObject, XRef *xref) :
   Object ocgList;
   ocgObject->dictLookup("OCGs", &ocgList);
   if (!ocgList.isArray()) {
-    error(-1, "Expected the optional content group list, but wasn't able to find it, or it isn't an Array");
+    error(errSyntaxError, -1, "Expected the optional content group list, but wasn't able to find it, or it isn't an Array");
     ocgList.free();
     ok = gFalse;
     return;
@@ -65,7 +65,7 @@ OCGs::OCGs(Object *ocgObject, XRef *xref) :
   Object defaultOcgConfig;
   ocgObject->dictLookup("D", &defaultOcgConfig);
   if (!defaultOcgConfig.isDict()) {
-    error(-1, "Expected the default config, but wasn't able to find it, or it isn't a Dictionary");
+    error(errSyntaxError, -1, "Expected the default config, but wasn't able to find it, or it isn't a Dictionary");
     defaultOcgConfig.free();
     ocgList.free();
     ok = gFalse;
@@ -99,7 +99,7 @@ OCGs::OCGs(Object *ocgObject, XRef *xref) :
       OptionalContentGroup *group = findOcgByRef( reference.getRef() );
       reference.free();
       if (!group) {
-	error(-1, "Couldn't find group for reference");
+	error(errSyntaxWarning, -1, "Couldn't find group for reference");
 	break;
       }
       group->setState(OptionalContentGroup::On);
@@ -122,7 +122,7 @@ OCGs::OCGs(Object *ocgObject, XRef *xref) :
       OptionalContentGroup *group = findOcgByRef( reference.getRef() );
       reference.free();
       if (!group) {
-	error(-1, "Couldn't find group for reference to set OFF");
+	error(errSyntaxWarning, -1, "Couldn't find group for reference to set OFF");
 	break;
       }
       group->setState(OptionalContentGroup::Off);
@@ -161,7 +161,7 @@ OptionalContentGroup* OCGs::findOcgByRef( const Ref &ref)
     }
   }
 
-  error(-1, "Could not find a OCG with Ref (%d:%d)", ref.num, ref.gen);
+  error(errSyntaxWarning, -1, "Could not find a OCG with Ref ({0:d}:{1:d})", ref.num, ref.gen);
 
   // not found
   return NULL;
@@ -177,7 +177,7 @@ bool OCGs::optContentIsVisible( Object *dictRef )
   bool result = true;
   dictRef->fetch( m_xref, &dictObj );
   if ( ! dictObj.isDict() ) {
-    error(-1, "Unexpected oc reference target: %i", dictObj.getType() );
+    error(errSyntaxWarning, -1, "Unexpected oc reference target: {0:d}", dictObj.getType() );
     dictObj.free();
     return result;
   }
@@ -290,7 +290,7 @@ OptionalContentGroup::OptionalContentGroup(Dict *ocgDict) : m_name(NULL)
   Object ocgName;
   ocgDict->lookup("Name", &ocgName);
   if (!ocgName.isString()) {
-    error(-1, "Expected the name of the OCG, but wasn't able to find it, or it isn't a String");
+    error(errSyntaxWarning, -1, "Expected the name of the OCG, but wasn't able to find it, or it isn't a String");
   } else {
     m_name = new GooString( ocgName.getString() );
   }
diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
index 51bb22b..3139ab2 100644
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@ -141,8 +141,7 @@ PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword,
     // Keep a copy of the errno returned by fopen so that it can be 
     // referred to later.
     fopenErrno = errno;
-    error(-1, "Couldn't open file '%s': %s.", fileName->getCString(),
-                                              strerror(errno));
+    error(errIO, -1, "Couldn't open file '{0:t}': {0:s}.", fileName, strerror(errno));
     errCode = errOpenFile;
     return;
   }
@@ -196,7 +195,7 @@ PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword,
     file = fopen(fileName->getCString(), "rb");
   }
   if (!file) {
-    error(-1, "Couldn't open file '%s'", fileName->getCString());
+    error(errIO, -1, "Couldn't open file '{0:t}'", fileName);
     errCode = errOpenFile;
     return;
   }
@@ -227,7 +226,7 @@ GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) {
   str->setPos(0, -1);
   if (str->getPos() < 0)
   {
-    error(-1, "Document base stream is not seekable");
+    error(errSyntaxError, -1, "Document base stream is not seekable");
     return gFalse;
   }
 
@@ -245,7 +244,7 @@ GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) {
   // read xref table
   xref = new XRef(str, getStartXRef(), getMainXRefEntriesOffset(), &wasReconstructed);
   if (!xref->isOk()) {
-    error(-1, "Couldn't read xref table");
+    error(errSyntaxError, -1, "Couldn't read xref table");
     errCode = xref->getErrorCode();
     return gFalse;
   }
@@ -269,7 +268,7 @@ GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) {
     }
 
     if (catalog && !catalog->isOk()) {
-      error(-1, "Couldn't read page catalog");
+      error(errSyntaxError, -1, "Couldn't read page catalog");
       errCode = errBadCatalog;
       return gFalse;
     }
@@ -343,7 +342,7 @@ GBool PDFDoc::checkFooter() {
   }
   if (!found)
   {
-    error(-1, "Document has not the mandatory ending %%EOF");
+    error(errSyntaxError, -1, "Document has not the mandatory ending %%EOF");
     errCode = errDamaged;
     delete[] eof;
     return gFalse;
@@ -373,12 +372,12 @@ void PDFDoc::checkHeader() {
     }
   }
   if (i >= headerSearchSize - 5) {
-    error(-1, "May not be a PDF file (continuing anyway)");
+    error(errSyntaxWarning, -1, "May not be a PDF file (continuing anyway)");
     return;
   }
   str->moveStart(i);
   if (!(p = strtok_r(&hdrBuf[i+5], " \t\n\r", &tokptr))) {
-    error(-1, "May not be a PDF file (continuing anyway)");
+    error(errSyntaxWarning, -1, "May not be a PDF file (continuing anyway)");
     return;
   }
   sscanf(p, "%d.%d", &pdfMajorVersion, &pdfMinorVersion);
@@ -535,7 +534,7 @@ GBool PDFDoc::getID(GooString *permanent_id, GooString *update_id) {
 	  return gFalse;
 	}
       } else {
-        error(-1, "Invalid permanent ID");
+        error(errSyntaxError, -1, "Invalid permanent ID");
 	obj2.free();
 	return gFalse;
       }
@@ -549,7 +548,7 @@ GBool PDFDoc::getID(GooString *permanent_id, GooString *update_id) {
 	  return gFalse;
 	}
       } else {
-        error(-1, "Invalid update ID");
+        error(errSyntaxError, -1, "Invalid update ID");
 	obj2.free();
 	return gFalse;
       }
@@ -582,7 +581,7 @@ int PDFDoc::savePageAs(GooString *name, int pageNo)
   int rootNum = getXRef()->getSize() + 1;
 
   if (pageNo < 1 || pageNo > getNumPages()) {
-    error(-1, "Illegal pageNo: %d(%d)", pageNo, getNumPages() );
+    error(errInternal, -1, "Illegal pageNo: {0:d}({1:d})", pageNo, getNumPages() );
     return errOpenFile;
   }
   PDFRectangle *cropBox = NULL;
@@ -598,7 +597,7 @@ int PDFDoc::savePageAs(GooString *name, int pageNo)
   getXRef()->fetch(refPage->num, refPage->gen, &page);
 
   if (!(f = fopen(name->getCString(), "wb"))) {
-    error(-1, "Couldn't open file '%s'", name->getCString());
+    error(errIO, -1, "Couldn't open file '{0:t}'", name);
     return errOpenFile;
   }
   outStr = new FileOutStream(f,0);
@@ -695,7 +694,7 @@ int PDFDoc::saveAs(GooString *name, PDFWriteMode mode) {
   int res;
 
   if (!(f = fopen(name->getCString(), "wb"))) {
-    error(-1, "Couldn't open file '%s'", name->getCString());
+    error(errIO, -1, "Couldn't open file '{0:t}'", name);
     return errOpenFile;
   }
   outStr = new FileOutStream(f,0);
@@ -747,7 +746,7 @@ int PDFDoc::saveWithoutChangesAs(GooString *name) {
   int res;
 
   if (!(f = fopen(name->getCString(), "wb"))) {
-    error(-1, "Couldn't open file '%s'", name->getCString());
+    error(errIO, -1, "Couldn't open file '{0:t}'", name);
     return errOpenFile;
   }
   
@@ -886,7 +885,7 @@ void PDFDoc::writeRawStream (Stream* str, OutStream* outStr)
   Object obj1;
   str->getDict()->lookup("Length", &obj1);
   if (!obj1.isInt()) {
-    error (-1, "PDFDoc::writeRawStream, no Length in stream dict");
+    error (errSyntaxError, -1, "PDFDoc::writeRawStream, no Length in stream dict");
     return;
   }
 
@@ -1046,7 +1045,7 @@ Guint PDFDoc::writeObject (Object* obj, Ref* ref, OutStream* outStr, XRef *xRef,
       outStr->printf("none\r\n");
       break;
     default:
-      error(-1,"Unhandled objType : %i, please report a bug with a testcase\r\n", obj->getType());
+      error(errUnimplemented, -1,"Unhandled objType : {0:d}, please report a bug with a testcase\r\n", obj->getType());
       break;
   }
   if (ref)
@@ -1107,7 +1106,7 @@ void PDFDoc::writeTrailer(Guint uxrefOffset, int uxrefSize,
     //only update the second part of the array
     xRef->getTrailerDict()->getDict()->lookup("ID", &obj4);
     if (!obj4.isArray()) {
-      error(-1, "PDFDoc::writeTrailer original file's ID entry isn't an array. Trying to continue");
+      error(errSyntaxWarning, -1, "PDFDoc::writeTrailer original file's ID entry isn't an array. Trying to continue");
     } else {
       //Get the first part of the ID
       obj4.arrayGet(0,&obj3); 
@@ -1472,13 +1471,13 @@ Page *PDFDoc::parsePage(int page)
 
   pageRef.num = getHints()->getPageObjectNum(page);
   if (!pageRef.num) {
-    error(-1, "Failed to get object num from hint tables for page %d", page);
+    error(errSyntaxWarning, -1, "Failed to get object num from hint tables for page {0:d}", page);
     return NULL;
   }
 
   // check for bogus ref - this can happen in corrupted PDF files
   if (pageRef.num < 0 || pageRef.num >= xref->getNumObjects()) {
-    error(-1, "Invalid object num (%d) for page %d", pageRef.num, page);
+    error(errSyntaxWarning, -1, "Invalid object num ({0:d}) for page {1:d}", pageRef.num, page);
     return NULL;
   }
 
@@ -1486,7 +1485,7 @@ Page *PDFDoc::parsePage(int page)
   xref->fetch(pageRef.num, pageRef.gen, &obj);
   if (!obj.isDict("Page")) {
     obj.free();
-    error(-1, "Object (%d %d) is not a pageDict", pageRef.num, pageRef.gen);
+    error(errSyntaxWarning, -1, "Object ({0:d} {1:d}) is not a pageDict", pageRef.num, pageRef.gen);
     return NULL;
   }
   pageDict = obj.getDict();
@@ -1515,7 +1514,7 @@ Page *PDFDoc::getPage(int page)
     if (pageCache[page-1]) {
        return pageCache[page-1];
     } else {
-       error(-1, "Failed parsing page %d using hint tables", page);
+       error(errSyntaxWarning, -1, "Failed parsing page {0:d} using hint tables", page);
     }
   }
 
diff --git a/poppler/PDFDocFactory.cc b/poppler/PDFDocFactory.cc
index 7829b3e..1ec4647 100644
--- a/poppler/PDFDocFactory.cc
+++ b/poppler/PDFDocFactory.cc
@@ -59,7 +59,7 @@ PDFDocFactory::createPDFDoc(const GooString &uri, GooString *ownerPassword,
     }
   }
 
-  error(-1, "Cannot handle URI '%s'.", uri.getCString());
+  error(errInternal, -1, "Cannot handle URI '{0:t}'.", &uri);
   GooString *fileName = uri.copy();
   return PDFDoc::ErrorPDFDoc(errOpenFile, fileName);
 }
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 9b0a634..63e4eae 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -1036,19 +1036,19 @@ PSOutputDev::PSOutputDev(const char *fileName, PDFDoc *doc, XRef *xrefA, Catalog
     signal(SIGPIPE, (SignalFunc)SIG_IGN);
 #endif
     if (!(f = popen(fileName + 1, "w"))) {
-      error(-1, "Couldn't run print command '%s'", fileName);
+      error(errIO, -1, "Couldn't run print command '{0:s}'", fileName);
       ok = gFalse;
       return;
     }
 #else
-    error(-1, "Print commands are not supported ('%s')", fileName);
+    error(errIO, -1, "Print commands are not supported ('{0:s}')", fileName);
     ok = gFalse;
     return;
 #endif
   } else {
     fileTypeA = psFile;
     if (!(f = fopen(fileName, "w"))) {
-      error(-1, "Couldn't open PostScript file '%s'", fileName);
+      error(errIO, -1, "Couldn't open PostScript file '{0:s}'", fileName);
       ok = gFalse;
       return;
     }
@@ -1126,7 +1126,7 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
       paperWidth = (int)ceil(page->getMediaWidth());
       paperHeight = (int)ceil(page->getMediaHeight());
     } else {
-      error(-1, "Invalid page %d", firstPage);
+      error(errSyntaxError, -1, "Invalid page {0:d}", firstPage);
       paperWidth = 1;
       paperHeight = 1;
     }
@@ -1201,7 +1201,7 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
 		  page->getRotate(),
 		  pstitle);
     } else {
-      error(-1, "Invalid page %d", firstPage);
+      error(errSyntaxError, -1, "Invalid page {0:d}", firstPage);
       box = new PDFRectangle(0, 0, 1, 1);
       writeHeader(firstPage, lastPage, box, box, 0, pstitle);
       delete box;
@@ -1446,7 +1446,7 @@ void PSOutputDev::writeDocSetup(PDFDoc *doc, Catalog *catalog,
   for (pg = firstPage; pg <= lastPage; ++pg) {
     page = doc->getPage(pg);
     if (!page) {
-      error(-1, "Failed writing resources for page %d", pg);
+      error(errSyntaxError, -1, "Failed writing resources for page {0:d}", pg);
       continue;
     }
     if ((resDict = page->getResourceDict())) {
@@ -1863,8 +1863,8 @@ void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
       uMap->decRefCnt();
       ++font16EncLen;
     } else {
-      error(-1, "Couldn't find Unicode map for 16-bit font encoding '%s'",
-	    font16Enc[font16EncLen].enc->getCString());
+      error(errSyntaxError, -1, "Couldn't find Unicode map for 16-bit font encoding '{0:t}'",
+	    font16Enc[font16EncLen].enc);
     }
 
     // try the display font for embedding
@@ -1877,7 +1877,7 @@ void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
 
   // give up - can't do anything with this font
   } else {
-    error(-1, "Couldn't find a font to substitute for '%s' ('%s' character collection)",
+    error(errSyntaxError, -1, "Couldn't find a font to substitute for '{0:s}' ('{1:s}' character collection)",
 	  font->getName() ? font->getName()->getCString() : "(unnamed)",
 	  ((GfxCIDFont *)font)->getCollection()
 	    ? ((GfxCIDFont *)font)->getCollection()->getCString()
@@ -1962,18 +1962,20 @@ void PSOutputDev::setupEmbeddedType1Font(Ref *id, GooString *psName) {
   refObj.fetch(xref, &strObj);
   refObj.free();
   if (!strObj.isStream()) {
-    error(-1, "Embedded font file object is not a stream");
+    error(errSyntaxError, -1, "Embedded font file object is not a stream");
     goto err1;
   }
   if (!(dict = strObj.streamGetDict())) {
-    error(-1, "Embedded font stream is missing its dictionary");
+    error(errSyntaxError, -1,
+	  "Embedded font stream is missing its dictionary");
     goto err1;
   }
   dict->lookup("Length1", &obj1);
   dict->lookup("Length2", &obj2);
   dict->lookup("Length3", &obj3);
   if (!obj1.isInt() || !obj2.isInt() || !obj3.isInt()) {
-    error(-1, "Missing length fields in embedded font stream dictionary");
+    error(errSyntaxError, -1,
+	  "Missing length fields in embedded font stream dictionary");
     obj1.free();
     obj2.free();
     obj3.free();
@@ -2003,7 +2005,8 @@ void PSOutputDev::setupEmbeddedType1Font(Ref *id, GooString *psName) {
   for (i = 0; i < 4; ++i) {
     start[i] = strObj.streamGetChar();
     if (start[i] == EOF) {
-      error(-1, "Unexpected end of file in embedded font stream");
+      error(errSyntaxError, -1,
+	    "Unexpected end of file in embedded font stream");
       goto err1;
     }
     if (!((start[i] >= '0' && start[i] <= '9') ||
@@ -2017,7 +2020,7 @@ void PSOutputDev::setupEmbeddedType1Font(Ref *id, GooString *psName) {
     // length2 == 0 is an error
     // trying to solve it by just piping all
     // the stream data
-    error(-1, "Font has length2 as 0, trying to overcome the problem reading the stream until the end");
+    error(errSyntaxWarning, -1, "Font has length2 as 0, trying to overcome the problem reading the stream until the end");
     length2 = INT_MAX;
     writePadding = gFalse;
   }
@@ -2120,7 +2123,7 @@ void PSOutputDev::setupExternalType1Font(GooString *fileName, GooString *psName)
 
   // copy the font file
   if (!(fontFile = fopen(fileName->getCString(), "rb"))) {
-    error(-1, "Couldn't open external font file");
+    error(errIO, -1, "Couldn't open external font file");
     return;
   }
   while ((c = fgetc(fontFile)) != EOF) {
@@ -2678,7 +2681,8 @@ void PSOutputDev::setupImages(Dict *resDict) {
 	  if (xObjRef.isRef()) {
 	    setupImage(xObjRef.getRef(), xObj.getStream());
 	  } else {
-	    error(-1, "Image in resource dict is not an indirect reference");
+	    error(errSyntaxError, -1,
+		  "Image in resource dict is not an indirect reference");
 	  }
 	}
 	subtypeObj.free();
@@ -2878,7 +2882,8 @@ void PSOutputDev::setupForms(Dict *resDict) {
 	  if (xObjRef.isRef()) {
 	    setupForm(xObjRef.getRef(), &xObj);
 	  } else {
-	    error(-1, "Form in resource dict is not an indirect reference");
+	    error(errSyntaxError, -1,
+		  "Form in resource dict is not an indirect reference");
 	  }
 	}
 	subtypeObj.free();
@@ -2922,7 +2927,7 @@ void PSOutputDev::setupForm(Ref id, Object *strObj) {
   dict->lookup("BBox", &bboxObj);
   if (!bboxObj.isArray()) {
     bboxObj.free();
-    error(-1, "Bad form bounding box");
+    error(errSyntaxError, -1, "Bad form bounding box");
     return;
   }
   for (i = 0; i < 4; ++i) {
@@ -3024,7 +3029,7 @@ GBool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/,
 				    paperColor, gTrue, gFalse);
 #else
   } else if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) {
-    error(-1, "pdftops was built without CMYK support, levelnsep needs it to work in this file");
+    error(errInternal, -1, "pdftops was built without CMYK support, levelnsep needs it to work in this file");
     return gFalse;
 #endif
   } else {
@@ -5552,7 +5557,7 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
     if (opi13Nest) {
       if (inlineImg) {
 	// this can't happen -- OPI dictionaries are in XObjects
-	error(-1, "Internal: OPI in inline image");
+	error(errSyntaxError, -1, "OPI in inline image");
 	n = 0;
       } else {
 	// need to read the stream to count characters -- the length
diff --git a/poppler/Page.cc b/poppler/Page.cc
index 96f4b51..95469f6 100644
--- a/poppler/Page.cc
+++ b/poppler/Page.cc
@@ -273,7 +273,7 @@ Page::Page(XRef *xrefA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attrs
   // transtion
   pageDict->lookupNF("Trans", &trans);
   if (!(trans.isRef() || trans.isDict() || trans.isNull())) {
-    error(-1, "Page transition object (page %d) is wrong type (%s)",
+    error(errSyntaxError, -1, "Page transition object (page {0:d}) is wrong type ({1:s})",
 	  num, trans.getTypeName());
     trans.free();
   }
@@ -281,7 +281,7 @@ Page::Page(XRef *xrefA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attrs
   // duration
   pageDict->lookupNF("Dur", &tmp);
   if (!(tmp.isNum() || tmp.isNull())) {
-    error(-1, "Page duration object (page %d) is wrong type (%s)",
+    error(errSyntaxError, -1, "Page duration object (page {0:d}) is wrong type ({1:s})",
 	  num, tmp.getTypeName());
   } else if (tmp.isNum()) {
     duration = tmp.getNum();
@@ -291,7 +291,7 @@ Page::Page(XRef *xrefA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attrs
   // annotations
   pageDict->lookupNF("Annots", &annotsObj);
   if (!(annotsObj.isRef() || annotsObj.isArray() || annotsObj.isNull())) {
-    error(-1, "Page annotations object (page %d) is wrong type (%s)",
+    error(errSyntaxError, -1, "Page annotations object (page {0:d}) is wrong type ({1:s})",
 	  num, annotsObj.getTypeName());
     annotsObj.free();
     goto err2;
@@ -301,7 +301,7 @@ Page::Page(XRef *xrefA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attrs
   pageDict->lookupNF("Contents", &contents);
   if (!(contents.isRef() || contents.isArray() ||
 	contents.isNull())) {
-    error(-1, "Page contents object (page %d) is wrong type (%s)",
+    error(errSyntaxError, -1, "Page contents object (page {0:d}) is wrong type ({1:s})",
 	  num, contents.getTypeName());
     contents.free();
     goto err1;
@@ -310,7 +310,7 @@ Page::Page(XRef *xrefA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attrs
   // thumb
   pageDict->lookupNF("Thumb", &thumb);
   if (!(thumb.isStream() || thumb.isNull() || thumb.isRef())) {
-      error(-1, "Page thumb object (page %d) is wrong type (%s)",
+      error(errSyntaxError, -1, "Page thumb object (page {0:d}) is wrong type ({1:s})",
             num, thumb.getTypeName());
       thumb.initNull(); 
   }
@@ -318,7 +318,7 @@ Page::Page(XRef *xrefA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attrs
   // actions
   pageDict->lookupNF("AA", &actions);
   if (!(actions.isDict() || actions.isNull())) {
-      error(-1, "Page additional action object (page %d) is wrong type (%s)",
+      error(errSyntaxError, -1, "Page additional action object (page {0:d}) is wrong type ({1:s})",
             num, actions.getTypeName());
       actions.initNull();
   }
diff --git a/poppler/Parser.cc b/poppler/Parser.cc
index 34a8286..fc935d2 100644
--- a/poppler/Parser.cc
+++ b/poppler/Parser.cc
@@ -92,7 +92,7 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey,
       obj->arrayAdd(getObj(&obj2, fileKey, encAlgorithm, keyLength,
 			   objNum, objGen, fetchOriginatorNums));
     if (buf1.isEOF())
-      error(getPos(), "End of file inside array");
+      error(errSyntaxError, getPos(), "End of file inside array");
     shift();
 
   // dictionary or stream
@@ -101,7 +101,7 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey,
     obj->initDict(xref);
     while (!buf1.isCmd(">>") && !buf1.isEOF()) {
       if (!buf1.isName()) {
-	error(getPos(), "Dictionary key must be a name object");
+	error(errSyntaxError, getPos(), "Dictionary key must be a name object");
 	shift();
       } else {
 	// buf1 might go away in shift(), so construct the key
@@ -115,7 +115,7 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey,
       }
     }
     if (buf1.isEOF())
-      error(getPos(), "End of file inside dictionary");
+      error(errSyntaxError, getPos(), "End of file inside dictionary");
     // stream objects are not allowed inside content streams or
     // object streams
     if (allowStreams && buf2.isCmd("stream")) {
@@ -190,7 +190,7 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
     length = (Guint)obj.getInt();
     obj.free();
   } else {
-    error(getPos(), "Bad 'Length' attribute in stream");
+    error(errSyntaxError, getPos(), "Bad 'Length' attribute in stream");
     obj.free();
     length = 0;
   }
@@ -221,7 +221,7 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
   if (buf1.isCmd("endstream")) {
     shift();
   } else {
-    error(getPos(), "Missing 'endstream'");
+    error(errSyntaxError, getPos(), "Missing 'endstream'");
     if (xref) {
       // shift until we find the proper endstream or we change to another object or reach eof
       while (!buf1.isCmd("endstream") && xref->getNumEntry(lexer->getPos()) == objNum && !buf1.isEOF()) {
diff --git a/poppler/Rendition.cc b/poppler/Rendition.cc
index b81e169..d00f555 100644
--- a/poppler/Rendition.cc
+++ b/poppler/Rendition.cc
@@ -308,7 +308,7 @@ MediaRendition::MediaRendition(Object* obj) {
 
 	  // TODO: D might be a form XObject too
 	} else {
-	  error (-1, "Invalid Media Clip Data");
+	  error (errSyntaxError, -1, "Invalid Media Clip Data");
 	  ok = gFalse;
 	}
 	obj1.free();
@@ -322,7 +322,7 @@ MediaRendition::MediaRendition(Object* obj) {
         // TODO
       }
     } else {
-      error (-1, "Invalid Media Clip");
+      error (errSyntaxError, -1, "Invalid Media Clip");
       ok = gFalse;
     }
     tmp.free();
@@ -345,7 +345,7 @@ MediaRendition::MediaRendition(Object* obj) {
     }
     params.free();
   } else if (hasClip) {
-    error (-1, "Invalid Media Rendition");
+    error (errSyntaxError, -1, "Invalid Media Rendition");
     ok = gFalse;
   }
   tmp2.free();
diff --git a/poppler/SecurityHandler.cc b/poppler/SecurityHandler.cc
index 1e847c9..3426df3 100644
--- a/poppler/SecurityHandler.cc
+++ b/poppler/SecurityHandler.cc
@@ -58,14 +58,14 @@ SecurityHandler *SecurityHandler::make(PDFDoc *docA, Object *encryptDictA) {
       secHdlr = new ExternalSecurityHandler(docA, encryptDictA, xsh);
     } else {
 #endif
-      error(/*errSyntaxError, */-1, "Couldn't find the '%s' security handler",
+      error(errSyntaxError, -1, "Couldn't find the '{0:s}' security handler",
 	    filterObj.getName());
       secHdlr = NULL;
 #ifdef ENABLE_PLUGINS
     }
 #endif
   } else {
-    error(/*errSyntaxError, */-1,
+    error(errSyntaxError, -1,
 	  "Missing or invalid 'Filter' entry in encryption dictionary");
     secHdlr = NULL;
   }
@@ -105,7 +105,7 @@ GBool SecurityHandler::checkEncryption(GooString *ownerPassword,
     }
   }
   if (!ok) {
-    error(/*errCommandLine, */-1, "Incorrect password");
+    error(errCommandLine, -1, "Incorrect password");
   }
   return ok;
 }
@@ -288,15 +288,15 @@ StandardSecurityHandler::StandardSecurityHandler(PDFDoc *docA,
 	}
 	ok = gTrue;
       } else if (!(encVersion == -1 && encRevision == -1)) {
-	error(/*errUnimplemented, */-1,
+	error(errUnimplemented, -1,
 	      "Unsupported version/revision (%d/%d) of Standard security handler",
 	      encVersion, encRevision);
       }
     } else {
-      error(/*errSyntaxError, */-1, "Invalid encryption key length");
+      error(errSyntaxError, -1, "Invalid encryption key length");
     }
   } else {
-    error(/*errSyntaxError, */-1, "Weird encryption info");
+    error(errSyntaxError, -1, "Weird encryption info");
   }
   fileIDObj.free();
   permObj.free();
diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index 97161d8..09815ba 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -1254,7 +1254,7 @@ T3FontCache::T3FontCache(Ref *fontIDA, double m11A, double m12A,
   if (glyphSize < 10485760 / cacheAssoc / cacheSets) {
     cacheData = (Guchar *)gmallocn_checkoverflow(cacheSets * cacheAssoc, glyphSize);
   } else {
-    error(-1, "Not creating cacheData for T3FontCache, it asked for too much memory.\n"
+    error(errSyntaxWarning, -1, "Not creating cacheData for T3FontCache, it asked for too much memory.\n"
               "       This could teoretically result in wrong rendering,\n"
               "       but most probably the document is bogus.\n"
               "       Please report a bug if you think the rendering may be wrong because of this.");
@@ -1784,7 +1784,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
         dfp = globalParams->getDisplayFont(gfxFont);
       }
       if (!dfp) {
-	error(-1, "Couldn't find a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't find a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -1816,7 +1816,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
 			   id,
 			   fontsrc,
 			   (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -1827,7 +1827,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
 			   id,
 			   fontsrc,
 			   (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -1838,7 +1838,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
 			   id,
 			   fontsrc,
 			   (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -1862,7 +1862,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
 			   id,
 			   fontsrc,
 			   codeToGID, n))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -1873,7 +1873,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
       if (!(fontFile = fontEngine->loadCIDFont(
 			   id,
 			   fontsrc))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -1883,7 +1883,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
       if (!(fontFile = fontEngine->loadOpenTypeCFFFont(
 			   id,
 			   fontsrc))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -1907,7 +1907,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
 	  ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
 	if (! ff)
 	{
-	  error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	  goto err2;
@@ -1919,7 +1919,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
 			   id,
 			   fontsrc,
 			   codeToGID, n, faceIndex))) {
-	error(-1, "Couldn't create a font for '%s'",
+	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
 	                         : "(unnamed)");
 	goto err2;
@@ -2305,17 +2305,17 @@ void SplashOutputDev::type3D1(GfxState *state, double wx, double wy,
   int i, j;
 
   if (unlikely(t3GlyphStack == NULL)) {
-    error(-1, "t3GlyphStack was null in SplashOutputDev::type3D1");
+    error(errSyntaxWarning, -1, "t3GlyphStack was null in SplashOutputDev::type3D1");
     return;
   }
 
   if (unlikely(t3GlyphStack->origBitmap != NULL)) {
-    error(-1, "t3GlyphStack origBitmap was not null in SplashOutputDev::type3D1");
+    error(errSyntaxWarning, -1, "t3GlyphStack origBitmap was not null in SplashOutputDev::type3D1");
     return;
   }
 
   if (unlikely(t3GlyphStack->origSplash != NULL)) {
-    error(-1, "t3GlyphStack origSplash was not null in SplashOutputDev::type3D1");
+    error(errSyntaxWarning, -1, "t3GlyphStack origSplash was not null in SplashOutputDev::type3D1");
     return;
   }
 
@@ -2364,7 +2364,7 @@ void SplashOutputDev::type3D1(GfxState *state, double wx, double wy,
       xMax - xt > t3Font->glyphX + t3Font->glyphW ||
       yMax - yt > t3Font->glyphY + t3Font->glyphH) {
     if (t3Font->validBBox) {
-      error(-1, "Bad bounding box in Type 3 glyph");
+      error(errSyntaxWarning, -1, "Bad bounding box in Type 3 glyph");
     }
     return;
   }
diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index f6f41fc..14cba9f 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -97,17 +97,17 @@ void Stream::close() {
 }
 
 int Stream::getRawChar() {
-  error(-1, "Internal: called getRawChar() on non-predictor stream");
+  error(errInternal, -1, "Internal: called getRawChar() on non-predictor stream");
   return EOF;
 }
 
 int Stream::getChars(int nChars, Guchar *buffer) {
-  error(-1, "Internal: called getChars() on non-predictor stream");
+  error(errInternal, -1, "Internal: called getChars() on non-predictor stream");
   return 0;
 }
 
 void Stream::getRawChars(int nChars, int *buffer) {
-  error(-1, "Internal: called getRawChars() on non-predictor stream");
+  error(errInternal, -1, "Internal: called getRawChars() on non-predictor stream");
 }
 
 char *Stream::getLine(char *buf, int size) {
@@ -164,14 +164,14 @@ Stream *Stream::addFilters(Object *dict) {
       if (obj2.isName()) {
 	str = makeFilter(obj2.getName(), str, &params2);
       } else {
-	error(getPos(), "Bad filter name");
+	error(errSyntaxError, getPos(), "Bad filter name");
 	str = new EOFStream(str);
       }
       obj2.free();
       params2.free();
     }
   } else if (!obj.isNull()) {
-    error(getPos(), "Bad 'Filter' attribute in stream");
+    error(errSyntaxError, getPos(), "Bad 'Filter' attribute in stream");
   }
   obj.free();
   params.free();
@@ -314,7 +314,7 @@ Stream *Stream::makeFilter(char *name, Stream *str, Object *params) {
   } else if (!strcmp(name, "JPXDecode")) {
     str = new JPXStream(str);
   } else {
-    error(getPos(), "Unknown filter '%s'", name);
+    error(errSyntaxError, getPos(), "Unknown filter '{0:s}'", name);
     str = new EOFStream(str);
   }
   return str;
@@ -399,7 +399,7 @@ void FilterStream::close() {
 }
 
 void FilterStream::setPos(Guint pos, int dir) {
-  error(-1, "Internal: called setPos() on FilterStream");
+  error(errInternal, -1, "Internal: called setPos() on FilterStream");
 }
 
 //------------------------------------------------------------------------
@@ -995,7 +995,7 @@ EmbedStream::~EmbedStream() {
 
 Stream *EmbedStream::makeSubStream(Guint start, GBool limitedA,
 				   Guint lengthA, Object *dictA) {
-  error(-1, "Internal: called makeSubStream() on EmbedStream");
+  error(errInternal, -1, "Called makeSubStream() on EmbedStream");
   return NULL;
 }
 
@@ -1015,16 +1015,16 @@ int EmbedStream::lookChar() {
 }
 
 void EmbedStream::setPos(Guint pos, int dir) {
-  error(-1, "Internal: called setPos() on EmbedStream");
+  error(errInternal, -1, "Internal: called setPos() on EmbedStream");
 }
 
 Guint EmbedStream::getStart() {
-  error(-1, "Internal: called getStart() on EmbedStream");
+  error(errInternal, -1, "Internal: called getStart() on EmbedStream");
   return 0;
 }
 
 void EmbedStream::moveStart(int delta) {
-  error(-1, "Internal: called moveStart() on EmbedStream");
+  error(errInternal, -1, "Internal: called moveStart() on EmbedStream");
 }
 
 //------------------------------------------------------------------------
@@ -1081,7 +1081,8 @@ int ASCIIHexStream::lookChar() {
     eof = gTrue;
     x = 0;
   } else {
-    error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
+    error(errSyntaxError, getPos(),
+	  "Illegal character <{0:02x}> in ASCIIHex stream", c1);
     x = 0;
   }
   if (c2 >= '0' && c2 <= '9') {
@@ -1094,7 +1095,8 @@ int ASCIIHexStream::lookChar() {
     eof = gTrue;
     x = 0;
   } else {
-    error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
+    error(errSyntaxError, getPos(),
+	  "Illegal character <{0:02x}> in ASCIIHex stream", c2);
   }
   buf = x & 0xff;
   return buf;
@@ -1295,7 +1297,8 @@ GBool LZWStream::processNextCode() {
     goto start;
   }
   if (nextCode >= 4097) {
-    error(getPos(), "Bad LZW stream - expected clear-table code");
+    error(errSyntaxError, getPos(),
+	  "Bad LZW stream - expected clear-table code");
     clearTable();
   }
 
@@ -1315,7 +1318,7 @@ GBool LZWStream::processNextCode() {
     seqBuf[seqLength] = newChar;
     ++seqLength;
   } else {
-    error(getPos(), "Bad LZW stream - unexpected code");
+    error(errSyntaxError, getPos(), "Bad LZW stream - unexpected code");
     eof = gTrue;
     return gFalse;
   }
@@ -1536,7 +1539,8 @@ void CCITTFaxStream::reset() {
 inline void CCITTFaxStream::addPixels(int a1, int blackPixels) {
   if (a1 > codingLine[a0i]) {
     if (a1 > columns) {
-      error(getPos(), "CCITTFax row is wrong length (%d)", a1);
+      error(errSyntaxError, getPos(),
+	    "CCITTFax row is wrong length ({0:d})", a1);
       err = gTrue;
       a1 = columns;
     }
@@ -1550,7 +1554,8 @@ inline void CCITTFaxStream::addPixels(int a1, int blackPixels) {
 inline void CCITTFaxStream::addPixelsNeg(int a1, int blackPixels) {
   if (a1 > codingLine[a0i]) {
     if (a1 > columns) {
-      error(getPos(), "CCITTFax row is wrong length (%d)", a1);
+      error(errSyntaxError, getPos(),
+	    "CCITTFax row is wrong length ({0:d})", a1);
       err = gTrue;
       a1 = columns;
     }
@@ -1560,7 +1565,7 @@ inline void CCITTFaxStream::addPixelsNeg(int a1, int blackPixels) {
     codingLine[a0i] = a1;
   } else if (a1 < codingLine[a0i]) {
     if (a1 < 0) {
-      error(getPos(), "Invalid CCITTFax code");
+      error(errSyntaxError, getPos(), "Invalid CCITTFax code");
       err = gTrue;
       a1 = 0;
     }
@@ -1729,7 +1734,8 @@ int CCITTFaxStream::lookChar() {
 	  eof = gTrue;
 	  break;
 	default:
-	  error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
+	  error(errSyntaxError, getPos(),
+		"Bad 2D code {0:04x} in CCITTFax stream", code1);
 	  addPixels(columns, 0);
 	  err = gTrue;
 	  break;
@@ -1799,7 +1805,8 @@ int CCITTFaxStream::lookChar() {
 	  for (i = 0; i < 4; ++i) {
 	    code1 = lookBits(12);
 	    if (code1 != 0x001) {
-	      error(getPos(), "Bad RTC code in CCITTFax stream");
+	      error(errSyntaxError, getPos(),
+		    "Bad RTC code in CCITTFax stream");
 	    }
 	    eatBits(12);
 	    if (encoding > 0) {
@@ -1911,7 +1918,8 @@ short CCITTFaxStream::getTwoDimCode() {
       }
     }
   }
-  error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code);
+  error(errSyntaxError, getPos(),
+	"Bad two dim code ({0:04x}) in CCITTFax stream", code);
   return EOF;
 }
 
@@ -1965,7 +1973,8 @@ short CCITTFaxStream::getWhiteCode() {
       }
     }
   }
-  error(getPos(), "Bad white code (%04x) in CCITTFax stream", code);
+  error(errSyntaxError, getPos(),
+	"Bad white code ({0:04x}) in CCITTFax stream", code);
   // eat a bit and return a positive number so that the caller doesn't
   // go into an infinite loop
   eatBits(1);
@@ -2040,7 +2049,8 @@ short CCITTFaxStream::getBlackCode() {
       }
     }
   }
-  error(getPos(), "Bad black code (%04x) in CCITTFax stream", code);
+  error(errSyntaxError, getPos(),
+	"Bad black code ({0:04x}) in CCITTFax stream", code);
   // eat a bit and return a positive number so that the caller doesn't
   // go into an infinite loop
   eatBits(1);
@@ -2253,7 +2263,7 @@ void DCTStream::reset() {
     bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
     if (bufWidth <= 0 || bufHeight <= 0 ||
 	bufWidth > INT_MAX / bufWidth / (int)sizeof(int)) {
-      error(getPos(), "Invalid image size in DCT stream");
+      error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
       y = height;
       return;
     }
@@ -2400,7 +2410,8 @@ GBool DCTStream::readMCURow() {
     if (restartInterval > 0 && restartCtr == 0) {
       c = readMarker();
       if (c != restartMarker) {
-	error(getPos(), "Bad DCT data: incorrect restart marker");
+	error(errSyntaxError, getPos(),
+	      "Bad DCT data: incorrect restart marker");
 	return gFalse;
       }
       if (++restartMarker == 0xd8)
@@ -2533,7 +2544,8 @@ void DCTStream::readScan() {
       if (restartInterval > 0 && restartCtr == 0) {
 	c = readMarker();
 	if (c != restartMarker) {
-	  error(getPos(), "Bad DCT data: incorrect restart marker");
+	  error(errSyntaxError, getPos(),
+		"Bad DCT data: incorrect restart marker");
 	  return;
 	}
 	if (++restartMarker == 0xd8) {
@@ -3103,7 +3115,7 @@ int DCTStream::readHuffSym(DCTHuffTable *table) {
     }
   } while (codeBits < 16);
 
-  error(getPos(), "Bad Huffman code in DCT stream");
+  error(errSyntaxError, getPos(), "Bad Huffman code in DCT stream");
   return 9999;
 }
 
@@ -3134,7 +3146,7 @@ int DCTStream::readBit() {
 	c2 = str->getChar();
       } while (c2 == 0xff);
       if (c2 != 0x00) {
-	error(getPos(), "Bad DCT data: missing 00 after ff");
+	error(errSyntaxError, getPos(), "Bad DCT data: missing 00 after ff");
 	return EOF;
       }
     }
@@ -3204,7 +3216,7 @@ GBool DCTStream::readHeader() {
       }
       break;
     case EOF:
-      error(getPos(), "Bad DCT header");
+      error(errSyntaxError, getPos(), "Bad DCT header");
       return gFalse;
     default:
       // skip APPn / COM / etc.
@@ -3214,7 +3226,7 @@ GBool DCTStream::readHeader() {
 	  str->getChar();
 	}
       } else {
-	error(getPos(), "Unknown DCT marker <%02x>", c);
+	error(errSyntaxError, getPos(), "Unknown DCT marker <{0:02x}>", c);
 	return gFalse;
       }
       break;
@@ -3236,12 +3248,12 @@ GBool DCTStream::readBaselineSOF() {
   width = read16();
   numComps = str->getChar();
   if (numComps <= 0 || numComps > 4) {
-    error(getPos(), "Bad number of components in DCT stream");
+    error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
     numComps = 0;
     return gFalse;
   }
   if (prec != 8) {
-    error(getPos(), "Bad DCT precision %d", prec);
+    error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
     return gFalse;
   }
   for (i = 0; i < numComps; ++i) {
@@ -3267,7 +3279,7 @@ GBool DCTStream::readProgressiveSOF() {
   width = read16();
   numComps = str->getChar();
   if (prec != 8) {
-    error(getPos(), "Bad DCT precision %d", prec);
+    error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
     return gFalse;
   }
   for (i = 0; i < numComps; ++i) {
@@ -3289,13 +3301,13 @@ GBool DCTStream::readScanInfo() {
   length = read16() - 2;
   scanInfo.numComps = str->getChar();
   if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) {
-    error(getPos(), "Bad number of components in DCT stream");
+    error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
     scanInfo.numComps = 0;
     return gFalse;
   }
   --length;
   if (length != 2 * scanInfo.numComps + 3) {
-    error(getPos(), "Bad DCT scan info block");
+    error(errSyntaxError, getPos(), "Bad DCT scan info block");
     return gFalse;
   }
   interleaved = scanInfo.numComps == numComps;
@@ -3318,7 +3330,8 @@ GBool DCTStream::readScanInfo() {
 	}
       }
       if (j == numComps) {
-	error(getPos(), "Bad DCT component ID in scan info block");
+	error(errSyntaxError, getPos(),
+	      "Bad DCT component ID in scan info block");
 	return gFalse;
       }
     }
@@ -3331,7 +3344,8 @@ GBool DCTStream::readScanInfo() {
   scanInfo.lastCoeff = str->getChar();
   if (scanInfo.firstCoeff < 0 || scanInfo.lastCoeff > 63 ||
       scanInfo.firstCoeff > scanInfo.lastCoeff) {
-    error(getPos(), "Bad DCT coefficient numbers in scan info block");
+    error(errSyntaxError, getPos(),
+	  "Bad DCT coefficient numbers in scan info block");
     return gFalse;
   }
   c = str->getChar();
@@ -3349,7 +3363,7 @@ GBool DCTStream::readQuantTables() {
     prec = (index >> 4) & 0x0f;
     index &= 0x0f;
     if (prec > 1 || index >= 4) {
-      error(getPos(), "Bad DCT quantization table");
+      error(errSyntaxError, getPos(), "Bad DCT quantization table");
       return gFalse;
     }
     if (index == numQuantTables) {
@@ -3385,7 +3399,7 @@ GBool DCTStream::readHuffmanTables() {
     index = str->getChar();
     --length;
     if ((index & 0x0f) >= 4) {
-      error(getPos(), "Bad DCT Huffman table");
+      error(errSyntaxError, getPos(), "Bad DCT Huffman table");
       return gFalse;
     }
     if (index & 0x10) {
@@ -3422,7 +3436,7 @@ GBool DCTStream::readRestartInterval() {
 
   length = read16();
   if (length != 4) {
-    error(getPos(), "Bad DCT restart interval");
+    error(errSyntaxError, getPos(), "Bad DCT restart interval");
     return gFalse;
   }
   restartInterval = read16();
@@ -3439,7 +3453,7 @@ GBool DCTStream::readJFIFMarker() {
   if (length >= 5) {
     for (i = 0; i < 5; ++i) {
       if ((c = str->getChar()) == EOF) {
-	error(getPos(), "Bad DCT APP0 marker");
+	error(errSyntaxError, getPos(), "Bad DCT APP0 marker");
 	return gFalse;
       }
       buf[i] = c;
@@ -3451,7 +3465,7 @@ GBool DCTStream::readJFIFMarker() {
   }
   while (length > 0) {
     if (str->getChar() == EOF) {
-      error(getPos(), "Bad DCT APP0 marker");
+      error(errSyntaxError, getPos(), "Bad DCT APP0 marker");
       return gFalse;
     }
     --length;
@@ -3487,7 +3501,7 @@ GBool DCTStream::readAdobeMarker() {
   return gTrue;
 
  err:
-  error(getPos(), "Bad DCT Adobe APP14 marker");
+  error(errSyntaxError, getPos(), "Bad DCT Adobe APP14 marker");
   return gFalse;
 }
 
@@ -3496,7 +3510,7 @@ GBool DCTStream::readTrailer() {
 
   c = readMarker();
   if (c != 0xd9) {		// EOI
-    error(getPos(), "Bad DCT trailer");
+    error(errSyntaxError, getPos(), "Bad DCT trailer");
     return gFalse;
   }
   return gTrue;
@@ -4234,15 +4248,15 @@ void FlateStream::reset() {
   if (cmf == EOF || flg == EOF)
     return;
   if ((cmf & 0x0f) != 0x08) {
-    error(getPos(), "Unknown compression method in flate stream");
+    error(errSyntaxError, getPos(), "Unknown compression method in flate stream");
     return;
   }
   if ((((cmf << 8) + flg) % 31) != 0) {
-    error(getPos(), "Bad FCHECK in flate stream");
+    error(errSyntaxError, getPos(), "Bad FCHECK in flate stream");
     return;
   }
   if (flg & 0x20) {
-    error(getPos(), "FDICT bit set in flate stream");
+    error(errSyntaxError, getPos(), "FDICT bit set in flate stream");
     return;
   }
 
@@ -4367,7 +4381,7 @@ void FlateStream::readSome() {
   return;
 
 err:
-  error(getPos(), "Unexpected end of file in flate stream");
+  error(errSyntaxError, getPos(), "Unexpected end of file in flate stream");
   endOfBlock = eof = gTrue;
   remain = 0;
 }
@@ -4409,7 +4423,7 @@ GBool FlateStream::startBlock() {
       goto err;
     check |= (c & 0xff) << 8;
     if (check != (~blockLen & 0xffff))
-      error(getPos(), "Bad uncompressed block length in flate stream");
+      error(errSyntaxError, getPos(), "Bad uncompressed block length in flate stream");
     codeBuf = 0;
     codeSize = 0;
 
@@ -4434,7 +4448,7 @@ GBool FlateStream::startBlock() {
   return gTrue;
 
 err:
-  error(getPos(), "Bad block header in flate stream");
+  error(errSyntaxError, getPos(), "Bad block header in flate stream");
   endOfBlock = eof = gTrue;
   return gFalse;
 }
@@ -4541,7 +4555,7 @@ GBool FlateStream::readDynamicCodes() {
   return gTrue;
 
 err:
-  error(getPos(), "Bad dynamic code table in flate stream");
+  error(errSyntaxError, getPos(), "Bad dynamic code table in flate stream");
   gfree(codeLenCodeTab.codes);
   return gFalse;
 }
diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc
index 213d97e..80ab9df 100644
--- a/poppler/TextOutputDev.cc
+++ b/poppler/TextOutputDev.cc
@@ -5171,7 +5171,7 @@ TextOutputDev::TextOutputDev(char *fileName, GBool physLayoutA,
     } else if ((outputStream = fopen(fileName, append ? "ab" : "wb"))) {
       needClose = gTrue;
     } else {
-      error(-1, "Couldn't open text file '%s'", fileName);
+      error(errIO, -1, "Couldn't open text file '{0:s}'", fileName);
       ok = gFalse;
       actualText = NULL;
       return;
diff --git a/poppler/UnicodeMap.cc b/poppler/UnicodeMap.cc
index fc86cea..0528cdf 100644
--- a/poppler/UnicodeMap.cc
+++ b/poppler/UnicodeMap.cc
@@ -60,8 +60,9 @@ UnicodeMap *UnicodeMap::parse(GooString *encodingNameA) {
   char *tokptr;
 
   if (!(f = globalParams->getUnicodeMapFile(encodingNameA))) {
-    error(-1, "Couldn't find unicodeMap file for the '%s' encoding",
-	  encodingNameA->getCString());
+    error(errSyntaxError, -1,
+	  "Couldn't find unicodeMap file for the '{0:t}' encoding",
+	  encodingNameA);
     return NULL;
   }
 
@@ -107,12 +108,14 @@ UnicodeMap *UnicodeMap::parse(GooString *encodingNameA) {
 	eMap->nBytes = nBytes;
 	++map->eMapsLen;
       } else {
-	error(-1, "Bad line (%d) in unicodeMap file for the '%s' encoding",
-	      line, encodingNameA->getCString());
+	error(errSyntaxError, -1,
+	      "Bad line ({0:d}) in unicodeMap file for the '{1:t}' encoding",
+	      line, encodingNameA);
       }
     } else {
-      error(-1, "Bad line (%d) in unicodeMap file for the '%s' encoding",
-	    line, encodingNameA->getCString());
+      error(errSyntaxError, -1,
+	    "Bad line ({0:d}) in unicodeMap file for the '{1:t}' encoding",
+	    line, encodingNameA);
     }
     ++line;
   }
diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index 8552b0f..901c4bc 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -166,7 +166,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
   // in the 'new Object[nObjects]' call (Acrobat apparently limits
   // object streams to 100-200 objects)
   if (nObjects > 1000000) {
-    error(-1, "Too many objects in an object stream");
+    error(errSyntaxError, -1, "Too many objects in an object stream");
     goto err1;
   }
   objs = new Object[nObjects];
@@ -319,7 +319,7 @@ XRef::XRef(BaseStream *strA, Guint pos, Guint mainXRefEntriesOffsetA, GBool *was
     // set size to (at least) the size specified in trailer dict
     trailerDict.dictLookupNF("Size", &obj);
     if (!obj.isInt()) {
-        error(-1, "No valid XRef size in trailer");
+        error(errSyntaxWarning, -1, "No valid XRef size in trailer");
     } else {
       if (obj.getInt() > size) {
          if (resize(obj.getInt()) != obj.getInt()) {
@@ -499,7 +499,7 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector<Guint> *follow
     }
     if (first + n > size) {
       if (resize(first + n) != first + n) {
-        error(-1, "Invalid 'obj' parameters'");
+        error(errSyntaxError, -1, "Invalid 'obj' parameters'");
         goto err0;
       }
     }
@@ -614,7 +614,7 @@ GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) {
   }
   if (newSize > size) {
     if (resize(newSize) != newSize) {
-      error(-1, "Invalid 'size' parameter");
+      error(errSyntaxError, -1, "Invalid 'size' parameter");
       goto err0;
     }
   }
@@ -696,7 +696,7 @@ GBool XRef::readXRefStreamSection(Stream *xrefStr, int *w, int first, int n) {
   }
   if (first + n > size) {
     if (resize(first + n) != size) {
-      error(-1, "Invalid 'size' inside xref table");
+      error(errSyntaxError, -1, "Invalid 'size' inside xref table");
       return gFalse;
     }
   }
@@ -769,7 +769,7 @@ GBool XRef::constructXRef(GBool *wasReconstructed) {
   size = 0;
   entries = NULL;
 
-  error(-1, "PDF file is damaged - attempting to reconstruct xref table...");
+  error(errSyntaxWarning, -1, "PDF file is damaged - attempting to reconstruct xref table...");
   gotRoot = gFalse;
   streamEndsLen = streamEndsSize = 0;
 
@@ -849,11 +849,11 @@ GBool XRef::constructXRef(GBool *wasReconstructed) {
 		  if (num >= size) {
 		    newSize = (num + 1 + 255) & ~255;
 		    if (newSize < 0) {
-		      error(-1, "Bad object number");
+		      error(errSyntaxError, -1, "Bad object number");
 		      return gFalse;
 		    }
 		    if (resize(newSize) != newSize) {
-		      error(-1, "Invalid 'obj' parameters");
+		      error(errSyntaxError, -1, "Invalid 'obj' parameters");
 		      return gFalse;
 		    }
 		  }
@@ -873,7 +873,7 @@ GBool XRef::constructXRef(GBool *wasReconstructed) {
         if (streamEndsLen == streamEndsSize) {
 	  streamEndsSize += 64;
           if (streamEndsSize >= INT_MAX / (int)sizeof(int)) {
-            error(-1, "Invalid 'endstream' parameter.");
+            error(errSyntaxError, -1, "Invalid 'endstream' parameter.");
             return gFalse;
           }
 	  streamEnds = (Guint *)greallocn(streamEnds,
@@ -895,7 +895,7 @@ GBool XRef::constructXRef(GBool *wasReconstructed) {
   if (gotRoot)
     return gTrue;
 
-  error(-1, "Couldn't find trailer dictionary");
+  error(errSyntaxError, -1, "Couldn't find trailer dictionary");
   return gFalse;
 }
 
@@ -1022,7 +1022,7 @@ Object *XRef::fetch(int num, int gen, Object *obj, std::set<int> *fetchOriginato
 	  long longNumber = strtol(cmd + 3, &end_ptr, 0);
 	  if (longNumber <= INT_MAX && longNumber >= INT_MIN && *end_ptr == '\0') {
 	    int number = longNumber;
-	    error(-1, "Cmd was not obj but %s, assuming the creator meant obj %d", cmd, number);
+	    error(errSyntaxWarning, -1, "Cmd was not obj but {0:s}, assuming the creator meant obj {1:d}", cmd, number);
 	    obj->initInt(number);
 	    obj1.free();
 	    obj2.free();
@@ -1180,7 +1180,7 @@ void XRef::add(int num, int gen, Guint offs, GBool used) {
 
 void XRef::setModifiedObject (Object* o, Ref r) {
   if (r.num < 0 || r.num >= size) {
-    error(-1,"XRef::setModifiedObject on unknown ref: %i, %i\n", r.num, r.gen);
+    error(errInternal, -1,"XRef::setModifiedObject on unknown ref: {0:d}, {1:d}\n", r.num, r.gen);
     return;
   }
   XRefEntry *e = getEntry(r.num);
@@ -1219,7 +1219,7 @@ Ref XRef::addIndirectObject (Object* o) {
 void XRef::writeToFile(OutStream* outStr, GBool writeAllEntries) {
   //create free entries linked-list
   if (getEntry(0)->gen != 65535) {
-    error(-1, "XRef::writeToFile, entry 0 of the XRef is invalid (gen != 65535)\n");
+    error(errInternal, -1, "XRef::writeToFile, entry 0 of the XRef is invalid (gen != 65535)\n");
   }
   int lastFreeEntry = 0;
   for (int i=0; i<size; i++) {
@@ -1299,7 +1299,7 @@ XRefEntry *XRef::getEntry(int i)
 
     if ((!xRefStream) && mainXRefEntriesOffset) {
       if (!parseEntry(mainXRefEntriesOffset + 20*i, &entries[i])) {
-        error(-1, "Failed to parse XRef entry [%d].", i);
+        error(errSyntaxError, -1, "Failed to parse XRef entry [{0:d}].", i);
       }
     } else {
       std::vector<Guint> followedPrev;
@@ -1312,7 +1312,7 @@ XRefEntry *XRef::getEntry(int i)
           }
         }
         if (followed) {
-          error(-1, "Circular XRef");
+          error(errSyntaxError, -1, "Circular XRef");
           if (!(ok = constructXRef(NULL))) {
             errCode = errDamaged;
           }
@@ -1339,7 +1339,7 @@ XRefEntry *XRef::getEntry(int i)
       }
 
       if (entries[i].type == xrefEntryNone) {
-         error(-1, "Invalid XRef entry");
+         error(errSyntaxError, -1, "Invalid XRef entry");
          entries[i].type = xrefEntryFree;
       }
     }
diff --git a/splash/Splash.cc b/splash/Splash.cc
index c385409..87dea06 100644
--- a/splash/Splash.cc
+++ b/splash/Splash.cc
@@ -3154,7 +3154,7 @@ void Splash::compositeBackground(SplashColorPtr color) {
   int x, y, mask;
 
   if (unlikely(bitmap->alpha == NULL)) {
-    error(-1, "bitmap->alpha is NULL in Splash::compositeBackground");
+    error(errInternal, -1, "bitmap->alpha is NULL in Splash::compositeBackground");
     return;
   }
 
diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc
index 562fbda..8d30c7e 100644
--- a/splash/SplashBitmap.cc
+++ b/splash/SplashBitmap.cc
@@ -218,7 +218,7 @@ SplashError SplashBitmap::writePNMFile(FILE *f) {
 #if SPLASH_CMYK
   case splashModeCMYK8:
     // PNM doesn't support CMYK
-    error(-1, "unsupported SplashBitmap mode");
+    error(errInternal, -1, "unsupported SplashBitmap mode");
     return splashErrGeneric;
     break;
 #endif
@@ -326,7 +326,7 @@ SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, FILE *f, in
     default:
       // Not the greatest error message, but users of this function should
       // have already checked whether their desired format is compiled in.
-      error(-1, "Support for this image type not compiled in");
+      error(errInternal, -1, "Support for this image type not compiled in");
       return splashErrGeneric;
   }
 
@@ -364,7 +364,7 @@ SplashError SplashBitmap::writeImgFile(ImgWriter *writer, FILE *f, int hDPI, int
       && mode != splashModeCMYK8
 #endif
      ) {
-    error(-1, "unsupported SplashBitmap mode");
+    error(errInternal, -1, "unsupported SplashBitmap mode");
     return splashErrGeneric;
   }
 
diff --git a/test/perf-test.cc b/test/perf-test.cc
index 94bddcd..6dc8e34 100644
--- a/test/perf-test.cc
+++ b/test/perf-test.cc
@@ -854,7 +854,7 @@ static void RenderPdfAsText(const char *fileName)
 
     pdfDoc = new PDFDoc(fileNameStr, NULL, NULL, NULL);
     if (!pdfDoc->isOk()) {
-        error(-1, "RenderPdfFile(): failed to open PDF file %s\n", fileName);
+        error(errIO, -1, "RenderPdfFile(): failed to open PDF file {0:s}\n", fileName);
         goto Exit;
     }
 
@@ -1225,7 +1225,7 @@ static void RenderCmdLineArg(char *cmdLineArg)
             RenderFileList(cmdLineArg);
 #endif
     } else {
-        error(-1, "unexpected argument '%s'", cmdLineArg);
+        error(errCommandLine, -1, "unexpected argument '{0:s}'", cmdLineArg);
     }
 }
 
diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc
index a3a99f5..a8a5922 100644
--- a/utils/HtmlOutputDev.cc
+++ b/utils/HtmlOutputDev.cc
@@ -757,7 +757,7 @@ int HtmlPage::dumpComplexHeaders(FILE * const file, FILE *& pageFile, int page)
       }
       delete pgNum;
       if (!pageFile) {
-	  error(-1, "Couldn't open html file '%s'", tmp->getCString());
+	  error(errIO, -1, "Couldn't open html file '{0:t}'", tmp);
 	  delete tmp;
 	  return 1;
       } 
@@ -791,7 +791,7 @@ void HtmlPage::dumpComplex(FILE *file, int page){
 
   if( firstPage == -1 ) firstPage = page; 
   
-  if (dumpComplexHeaders(file, pageFile, page)) { error(-1, "Couldn't write headers."); return; }
+  if (dumpComplexHeaders(file, pageFile, page)) { error(errIO, -1, "Couldn't write headers."); return; }
 
   tmp=basename(DocName);
    
@@ -979,7 +979,7 @@ void HtmlOutputDev::doFrame(int firstPage){
   fName->append(".html");
 
   if (!(fContentsFrame = fopen(fName->getCString(), "w"))){
-    error(-1, "Couldn't open html file '%s'", fName->getCString());
+    error(errIO, -1, "Couldn't open html file '{0:t}'", fName);
     delete fName;
     return;
   }
@@ -1056,7 +1056,7 @@ HtmlOutputDev::HtmlOutputDev(char *fileName, char *title,
 
          if (!(fContentsFrame = fopen(left->getCString(), "w")))
          {
-             error(-1, "Couldn't open html file '%s'", left->getCString());
+             error(errIO, -1, "Couldn't open html file '{0:t}'", left);
              delete left;
              return;
          }
@@ -1078,7 +1078,7 @@ HtmlOutputDev::HtmlOutputDev(char *fileName, char *title,
        right->append("s.html");
 
        if (!(page=fopen(right->getCString(),"w"))){
-        error(-1, "Couldn't open html file '%s'", right->getCString());
+        error(errIO, -1, "Couldn't open html file '{0:t}'", right);
         delete right;
 		return;
        }
@@ -1095,7 +1095,7 @@ HtmlOutputDev::HtmlOutputDev(char *fileName, char *title,
       if (!xml) right->append(".html");
       if (xml) right->append(".xml");
       if (!(page=fopen(right->getCString(),"w"))){
-	error(-1, "Couldn't open html file '%s'", right->getCString());
+	error(errIO, -1, "Couldn't open html file '{0:t}'", right);
 	delete right;
 	return;
       }  
@@ -1260,7 +1260,7 @@ void HtmlOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
 
     ++imgNum;
     if (!(f1 = fopen(fName->getCString(), "wb"))) {
-      error(-1, "Couldn't open image file '%s'", fName->getCString());
+      error(errIO, -1, "Couldn't open image file '{0:t}'", fName);
       delete fName;
       return;
     }
@@ -1312,7 +1312,7 @@ void HtmlOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
     ++imgNum;
     
     if (!(f1 = fopen(fName->getCString(), "wb"))) {
-      error(-1, "Couldn't open image file '%s'", fName->getCString());
+      error(errIO, -1, "Couldn't open image file '{0:t}'", fName);
       delete fName;
       return;
     }
@@ -1349,7 +1349,7 @@ void HtmlOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
 
     // Open the image file
     if (!(f1 = fopen(fName->getCString(), "wb"))) {
-      error(-1, "Couldn't open image file '%s'", fName->getCString());
+      error(errIO, -1, "Couldn't open image file '{0:t}'", fName);
       delete fName;
       return;
     }
diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc
index 88305a1..99b3319 100644
--- a/utils/ImageOutputDev.cc
+++ b/utils/ImageOutputDev.cc
@@ -84,7 +84,7 @@ void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
     setFilename("jpg");
     ++imgNum;
     if (!(f = fopen(fileName, "wb"))) {
-      error(-1, "Couldn't open image file '%s'", fileName);
+      error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
       return;
     }
 
@@ -106,7 +106,7 @@ void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
     setFilename("pbm");
     ++imgNum;
     if (!(f = fopen(fileName, "wb"))) {
-      error(-1, "Couldn't open image file '%s'", fileName);
+      error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
       return;
     }
     fprintf(f, "P4\n");
@@ -151,7 +151,7 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
     setFilename("jpg");
     ++imgNum;
     if (!(f = fopen(fileName, "wb"))) {
-      error(-1, "Couldn't open image file '%s'", fileName);
+      error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
       return;
     }
 
@@ -174,7 +174,7 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
     setFilename("pbm");
     ++imgNum;
     if (!(f = fopen(fileName, "wb"))) {
-      error(-1, "Couldn't open image file '%s'", fileName);
+      error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
       return;
     }
     fprintf(f, "P4\n");
@@ -205,7 +205,7 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
     setFilename("ppm");
     ++imgNum;
     if (!(f = fopen(fileName, "wb"))) {
-      error(-1, "Couldn't open image file '%s'", fileName);
+      error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
       return;
     }
     fprintf(f, "P6\n");
diff --git a/utils/pdfextract.cc b/utils/pdfextract.cc
index c8c4749..2d3b020 100644
--- a/utils/pdfextract.cc
+++ b/utils/pdfextract.cc
@@ -47,11 +47,11 @@ bool extractPages (const char *srcFileName, const char *destFileName) {
   PDFDoc *doc = new PDFDoc (gfileName, NULL, NULL, NULL);
 
   if (!doc->isOk()) {
-    error(-1, "Could not extract page(s) from damaged file ('%s')", srcFileName);
+    error(errSyntaxError, -1, "Could not extract page(s) from damaged file ('{0:s}')", srcFileName);
     return false;
   }
   if (doc->isEncrypted()) {
-    error(-1, "Could not extract page(s) from encrypted file ('%s')", srcFileName);
+    error(errSyntaxError, -1, "Could not extract page(s) from encrypted file ('{0:s}')", srcFileName);
     return false;
   }
 
diff --git a/utils/pdfimages.cc b/utils/pdfimages.cc
index ac47331..2383b6b 100644
--- a/utils/pdfimages.cc
+++ b/utils/pdfimages.cc
@@ -150,7 +150,7 @@ int main(int argc, char *argv[]) {
   // check for copy permission
 #ifdef ENFORCE_PERMISSIONS
   if (!doc->okToCopy()) {
-    error(-1, "Copying of images from this document is not allowed.");
+    error(errNotAllowed, -1, "Copying of images from this document is not allowed.");
     exitCode = 3;
     goto err1;
   }
diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc
index 314d874..6ea712b 100644
--- a/utils/pdfinfo.cc
+++ b/utils/pdfinfo.cc
@@ -146,7 +146,7 @@ int main(int argc, char *argv[]) {
 
   // get mapping to output encoding
   if (!(uMap = globalParams->getTextEncoding())) {
-    error(-1, "Couldn't get text encoding");
+    error(errCommandLine, -1, "Couldn't get text encoding");
     delete fileName;
     goto err1;
   }
@@ -262,7 +262,7 @@ int main(int argc, char *argv[]) {
       for (pg = firstPage; pg <= lastPage; ++pg) {
 	page = doc->getPage(pg);
 	if (!page) {
-          error(-1, "Failed to print boxes for page %d", pg);
+          error(errSyntaxError, -1, "Failed to print boxes for page {0:d}", pg);
 	  continue;
 	}
 	sprintf(buf, "Page %4d MediaBox: ", pg);
@@ -279,7 +279,7 @@ int main(int argc, char *argv[]) {
     } else {
       page = doc->getPage(firstPage);
       if (!page) {
-        error(-1, "Failed to print boxes for page %d", firstPage);
+        error(errSyntaxError, -1, "Failed to print boxes for page {0:d}", firstPage);
       } else {
         printBox("MediaBox:       ", page->getMediaBox());
         printBox("CropBox:        ", page->getCropBox());
diff --git a/utils/pdfmerge.cc b/utils/pdfmerge.cc
index 28f7265..2a44b5f 100644
--- a/utils/pdfmerge.cc
+++ b/utils/pdfmerge.cc
@@ -81,16 +81,16 @@ int main (int argc, char *argv[])
         }
       }
     } else if (doc->isOk()) {
-      error(-1, "Could not merge encrypted files ('%s')", argv[i]);
+      error(errUnimplemented, -1, "Could not merge encrypted files ('{0:s}')", argv[i]);
       return -1;
     } else {
-      error(-1, "Could not merge damaged documents ('%s')", argv[i]);
+      error(errSyntaxError, -1, "Could not merge damaged documents ('{0:s}')", argv[i]);
       return -1;
     }
   }
 
   if (!(f = fopen(fileName, "wb"))) {
-    error(-1, "Could not open file '%s'", fileName);
+    error(errIO, -1, "Could not open file '{0:s}'", fileName);
     return -1;
   }
   outStr = new FileOutStream(f, 0);
diff --git a/utils/pdftocairo.cc b/utils/pdftocairo.cc
index 4928657..b425c1e 100644
--- a/utils/pdftocairo.cc
+++ b/utils/pdftocairo.cc
@@ -531,7 +531,7 @@ static void renderPage(PDFDoc *doc, CairoOutputDev *cairoOut, int pg,
 
   status = cairo_status(cr);
   if (status)
-      error(-1, "cairo error: %s\n", cairo_status_to_string(status));
+      error(errInternal, -1, "cairo error: {0:s}\n", cairo_status_to_string(status));
   cairo_destroy (cr);
 }
 
@@ -546,7 +546,7 @@ static void endPage(GooString *imageFileName)
     cairo_surface_finish(surface);
     status = cairo_surface_status(surface);
     if (status)
-      error(-1, "cairo error: %s\n", cairo_status_to_string(status));
+      error(errInternal, -1, "cairo error: {0:s}\n", cairo_status_to_string(status));
     cairo_surface_destroy(surface);
   }
 
@@ -560,7 +560,7 @@ static void endDocument()
     cairo_surface_finish(surface);
     status = cairo_surface_status(surface);
     if (status)
-      error(-1, "cairo error: %s\n", cairo_status_to_string(status));
+      error(errInternal, -1, "cairo error: {0:s}\n", cairo_status_to_string(status));
     cairo_surface_destroy(surface);
     fclose(output_file);
   }
diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc
index 9c9024b..4d0d590 100644
--- a/utils/pdftohtml.cc
+++ b/utils/pdftohtml.cc
@@ -252,7 +252,7 @@ int main(int argc, char *argv[]) {
   // check for copy permission
   if (!doc->okToCopy()) {
     if (!noDrm) {
-      error(-1, "Copying of text from this document is not allowed.");
+      error(errNotAllowed, -1, "Copying of text from this document is not allowed.");
       goto error;
     }
     fprintf(stderr, "Document has copy-protection bit set.\n");
@@ -281,7 +281,7 @@ int main(int argc, char *argv[]) {
     }
     delete tmp;
   } else if (fileName->cmp("fd://0") == 0) {
-      error(-1, "You have to provide an output filename when reading form stdin.");
+      error(errCommandLine, -1, "You have to provide an output filename when reading form stdin.");
       goto error;
   } else {
     p = fileName->getCString() + fileName->getLength() - 4;
@@ -482,7 +482,7 @@ int main(int argc, char *argv[]) {
       gsCmd->append("\"");
       //    printf("running: %s\n", gsCmd->getCString());
       if( !executeCommand(gsCmd->getCString()) && !errQuiet) {
-        error(-1, "Failed to launch Ghostscript!\n");
+        error(errIO, -1, "Failed to launch Ghostscript!\n");
       }
       unlink(psFileName->getCString());
       delete tw;
diff --git a/utils/pdftops.cc b/utils/pdftops.cc
index 863fb98..195d179 100644
--- a/utils/pdftops.cc
+++ b/utils/pdftops.cc
@@ -337,7 +337,7 @@ int main(int argc, char *argv[]) {
 #ifdef ENFORCE_PERMISSIONS
   // check for print permission
   if (!doc->okToPrint()) {
-    error(-1, "Printing this document is not allowed.");
+    error(errNotAllowed, -1, "Printing this document is not allowed.");
     exitCode = 3;
     goto err1;
   }
@@ -347,7 +347,7 @@ int main(int argc, char *argv[]) {
   if (argc == 3) {
     psFileName = new GooString(argv[2]);
   } else if (fileName->cmp("fd://0") == 0) {
-    error(-1, "You have to provide an output filename when reading form stdin.");
+    error(errCommandLine, -1, "You have to provide an output filename when reading form stdin.");
     goto err1;
   } else {
     p = fileName->getCString() + fileName->getLength() - 4;
@@ -370,7 +370,7 @@ int main(int argc, char *argv[]) {
 
   // check for multi-page EPS or form
   if ((doEPS || doForm) && firstPage != lastPage) {
-    error(-1, "EPS and form files can only contain one page.");
+    error(errCommandLine, -1, "EPS and form files can only contain one page.");
     goto err2;
   }
 
diff --git a/utils/pdftotext.cc b/utils/pdftotext.cc
index 48b5c5a..2e7b32e 100644
--- a/utils/pdftotext.cc
+++ b/utils/pdftotext.cc
@@ -215,7 +215,7 @@ int main(int argc, char *argv[]) {
 
   // get mapping to output encoding
   if (!(uMap = globalParams->getTextEncoding())) {
-    error(-1, "Couldn't get text encoding");
+    error(errCommandLine, -1, "Couldn't get text encoding");
     delete fileName;
     goto err1;
   }
@@ -253,7 +253,7 @@ int main(int argc, char *argv[]) {
 #ifdef ENFORCE_PERMISSIONS
   // check for copy permission
   if (!doc->okToCopy()) {
-    error(-1, "Copying of text from this document is not allowed.");
+    error(errNotAllowed, -1, "Copying of text from this document is not allowed.");
     exitCode = 3;
     goto err2;
   }
@@ -263,7 +263,7 @@ int main(int argc, char *argv[]) {
   if (argc == 3) {
     textFileName = new GooString(argv[2]);
   } else if (fileName->cmp("fd://0") == 0) {
-     error(-1, "You have to provide an output filename when reading form stdin.");
+     error(errCommandLine, -1, "You have to provide an output filename when reading form stdin.");
      goto err2;
   } else {
     p = fileName->getCString() + fileName->getLength() - 4;
@@ -290,7 +290,7 @@ int main(int argc, char *argv[]) {
       f = stdout;
     } else {
       if (!(f = fopen(textFileName->getCString(), "wb"))) {
-	error(-1, "Couldn't open text file '%s'", textFileName->getCString());
+	error(errIO, -1, "Couldn't open text file '{0:t}'", textFileName);
 	exitCode = 2;
 	goto err3;
       }
@@ -335,7 +335,7 @@ int main(int argc, char *argv[]) {
   if (bbox) {
     textOut = new TextOutputDev(NULL, physLayout, rawOrder, htmlMeta);
     if (!(f = fopen(textFileName->getCString(), "ab"))) {
-      error(-1, "Couldn't open text file '%s' for append", textFileName->getCString());
+      error(errIO, -1, "Couldn't open text file '{0:t}' for append", textFileName);
       exitCode = 2;
       delete textOut;
       goto err3;
@@ -395,7 +395,7 @@ int main(int argc, char *argv[]) {
       f = stdout;
     } else {
       if (!(f = fopen(textFileName->getCString(), "ab"))) {
-	error(-1, "Couldn't open text file '%s'", textFileName->getCString());
+	error(errIO, -1, "Couldn't open text file '{0:t}'", textFileName);
 	exitCode = 2;
 	goto err3;
       }


More information about the poppler mailing list