From e3ec3d8e589335cca076d620cc98741cf1c73f98 Mon Sep 17 00:00:00 2001
From: Luigi Scarso <luigi.scarso@gmail.com>
Date: Mon, 15 Jan 2018 14:13:47 +0000
Subject: [PATCH] delete missed files

---
 .../poppler/poppler-src/poppler/Lexer.cc.orig |  641 ------
 .../poppler/poppler-src/poppler/Object.h.orig |  416 ----
 .../poppler/poppler-src/poppler/Object.h~     |  416 ----
 .../poppler-src/poppler/PDFDoc.cc.orig        | 1985 -----------------
 .../poppler/poppler-src/poppler/PDFDoc.cc~    | 1985 -----------------
 5 files changed, 5443 deletions(-)
 delete mode 100644 source/libs/poppler/poppler-src/poppler/Lexer.cc.orig
 delete mode 100644 source/libs/poppler/poppler-src/poppler/Object.h.orig
 delete mode 100644 source/libs/poppler/poppler-src/poppler/Object.h~
 delete mode 100644 source/libs/poppler/poppler-src/poppler/PDFDoc.cc.orig
 delete mode 100644 source/libs/poppler/poppler-src/poppler/PDFDoc.cc~

diff --git a/source/libs/poppler/poppler-src/poppler/Lexer.cc.orig b/source/libs/poppler/poppler-src/poppler/Lexer.cc.orig
deleted file mode 100644
index d2329b536..000000000
--- a/source/libs/poppler/poppler-src/poppler/Lexer.cc.orig
+++ /dev/null
@@ -1,641 +0,0 @@
-//========================================================================
-//
-// Lexer.cc
-//
-// Copyright 1996-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-//========================================================================
-//
-// Modified under the Poppler project - http://poppler.freedesktop.org
-//
-// All changes made under the Poppler project to this file are licensed
-// under GPL version 2 or later
-//
-// Copyright (C) 2006-2010, 2012-2014, 2017 Albert Astals Cid <aacid@kde.org>
-// Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
-// Copyright (C) 2010 Carlos Garcia Campos <carlosgc@gnome.org>
-// Copyright (C) 2012, 2013 Adrian Johnson <ajohnson@redneon.com>
-// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
-//
-// To see a description of the changes please see the Changelog file that
-// came with your tarball or type make ChangeLog if you are building from git
-//
-//========================================================================
-
-#include <config.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <limits.h>
-#include <ctype.h>
-#include "Lexer.h"
-#include "Error.h"
-#include "XRef.h"
-
-//------------------------------------------------------------------------
-
-// A '1' in this array means the character is white space.  A '1' or
-// '2' means the character ends a name or command.
-static const char specialChars[256] = {
-  1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0,   // 0x
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   // 1x
-  1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2,   // 2x
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0,   // 3x
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   // 4x
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0,   // 5x
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   // 6x
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0,   // 7x
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   // 8x
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   // 9x
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   // ax
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   // bx
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   // cx
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   // dx
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   // ex
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0    // fx
-};
-
-static const int IntegerSafeLimit = (INT_MAX - 9) / 10;
-static const long long LongLongSafeLimit = (LLONG_MAX - 9) / 10;
-
-//------------------------------------------------------------------------
-// Lexer
-//------------------------------------------------------------------------
-
-Lexer::Lexer(XRef *xrefA, Stream *str) {
-  lookCharLastValueCached = LOOK_VALUE_NOT_CACHED;
-  xref = xrefA;
-
-  curStr = Object(str);
-  streams = new Array(xref);
-  streams->add(curStr.copy());
-  strPtr = 0;
-  freeArray = gTrue;
-  curStr.streamReset();
-}
-
-Lexer::Lexer(XRef *xrefA, Object *obj) {
-  lookCharLastValueCached = LOOK_VALUE_NOT_CACHED;
-  xref = xrefA;
-
-  if (obj->isStream()) {
-    Object obj2;
-    streams = new Array(xref);
-    freeArray = gTrue;
-    streams->add(obj->copy());
-  } else {
-    streams = obj->getArray();
-    freeArray = gFalse;
-  }
-  strPtr = 0;
-  if (streams->getLength() > 0) {
-    curStr = streams->get(strPtr);
-    curStr.streamReset();
-  }
-}
-
-Lexer::~Lexer() {
-  if (!curStr.isNone()) {
-    curStr.streamClose();
-  }
-  if (freeArray) {
-    delete streams;
-  }
-}
-
-int Lexer::getChar(GBool comesFromLook) {
-  int c;
-
-  if (LOOK_VALUE_NOT_CACHED != lookCharLastValueCached) {
-    c = lookCharLastValueCached;
-    lookCharLastValueCached = LOOK_VALUE_NOT_CACHED;
-    return c;
-  }
-
-  c = EOF;
-  while (!curStr.isNone() && (c = curStr.streamGetChar()) == EOF) {
-    if (comesFromLook == gTrue) {
-      return EOF;
-    } else {
-      curStr.streamClose();
-      curStr = Object();
-      ++strPtr;
-      if (strPtr < streams->getLength()) {
-        curStr = streams->get(strPtr);
-        curStr.streamReset();
-      }
-    }
-  }
-  return c;
-}
-
-int Lexer::lookChar() {
-  
-  if (LOOK_VALUE_NOT_CACHED != lookCharLastValueCached) {
-    return lookCharLastValueCached;
-  }
-  lookCharLastValueCached = getChar(gTrue);
-  if (lookCharLastValueCached == EOF) {
-    lookCharLastValueCached = LOOK_VALUE_NOT_CACHED;
-    return EOF;
-  } else {
-    return lookCharLastValueCached;
-  }
-}
-
-Object Lexer::getObj(int objNum) {
-  char *p;
-  int c, c2;
-  GBool comment, neg, done, overflownInteger, overflownLongLong;
-  int numParen;
-  int xi;
-  long long xll = 0;
-  double xf = 0, scale;
-  GooString *s;
-  int n, m;
-
-  // skip whitespace and comments
-  comment = gFalse;
-  while (1) {
-    if ((c = getChar()) == EOF) {
-      return Object(objEOF);
-    }
-    if (comment) {
-      if (c == '\r' || c == '\n')
-	comment = gFalse;
-    } else if (c == '%') {
-      comment = gTrue;
-    } else if (specialChars[c] != 1) {
-      break;
-    }
-  }
-
-  // start reading token
-  switch (c) {
-
-  // number
-  case '0': case '1': case '2': case '3': case '4':
-  case '5': case '6': case '7': case '8': case '9':
-  case '+': case '-': case '.':
-    overflownInteger = gFalse;
-    overflownLongLong = gFalse;
-    neg = gFalse;
-    xi = 0;
-    if (c == '-') {
-      neg = gTrue;
-    } else if (c == '.') {
-      goto doReal;
-    } else if (c != '+') {
-      xi = c - '0';
-    }
-    while (1) {
-      c = lookChar();
-      if (isdigit(c)) {
-	getChar();
-	if (unlikely(overflownLongLong)) {
-	  xf = xf * 10.0 + (c - '0');
-	} else if (unlikely (overflownInteger)) {
-	  if (unlikely(xll > LongLongSafeLimit) &&
-	      (xll > (LLONG_MAX - (c - '0')) / 10.0)) {
-	    overflownLongLong = gTrue;
-	    xf = xll * 10.0 + (c - '0');
-	  } else {
-	    xll = xll * 10 + (c - '0');
-	  }
-	} else {
-	  if (unlikely(xi > IntegerSafeLimit) &&
-	      (xi > (INT_MAX - (c - '0')) / 10.0)) {
-	    overflownInteger = gTrue;
-	    xll = xi * 10LL + (c - '0');
-	  } else {
-	    xi = xi * 10 + (c - '0');
-	  }
-	}
-      } else if (c == '.') {
-	getChar();
-	goto doReal;
-      } else {
-	break;
-      }
-    }
-    if (neg) {
-      xi = -xi;
-      xll = -xll;
-      xf = -xf;
-    }
-    if (unlikely(overflownInteger)) {
-      if (overflownLongLong) {
-        return Object(xf);
-      } else {
-        if (unlikely(xll == INT_MIN)) {
-          return Object(static_cast<int>(INT_MIN));
-        } else {
-          return Object(xll);
-        }
-      }
-    } else {
-      return Object(xi);
-    }
-    break;
-  doReal:
-    if (likely(!overflownInteger)) {
-      xf = xi;
-    } else if (!overflownLongLong) {
-      xf = xll;
-    }
-    scale = 0.1;
-    while (1) {
-      c = lookChar();
-      if (c == '-') {
-	// ignore minus signs in the middle of numbers to match
-	// Adobe's behavior
-	error(errSyntaxWarning, getPos(), "Badly formatted number");
-	getChar();
-	continue;
-      }
-      if (!isdigit(c)) {
-	break;
-      }
-      getChar();
-      xf = xf + scale * (c - '0');
-      scale *= 0.1;
-    }
-    if (neg) {
-      xf = -xf;
-    }
-    return Object(xf);
-    break;
-
-  // string
-  case '(':
-    p = tokBuf;
-    n = 0;
-    numParen = 1;
-    done = gFalse;
-    s = NULL;
-    do {
-      c2 = EOF;
-      switch (c = getChar()) {
-
-      case EOF:
-#if 0
-      // This breaks some PDF files, e.g., ones from Photoshop.
-      case '\r':
-      case '\n':
-#endif
-	error(errSyntaxError, getPos(), "Unterminated string");
-	done = gTrue;
-	break;
-
-      case '(':
-	++numParen;
-	c2 = c;
-	break;
-
-      case ')':
-	if (--numParen == 0) {
-	  done = gTrue;
-	} else {
-	  c2 = c;
-	}
-	break;
-
-      case '\\':
-	switch (c = getChar()) {
-	case 'n':
-	  c2 = '\n';
-	  break;
-	case 'r':
-	  c2 = '\r';
-	  break;
-	case 't':
-	  c2 = '\t';
-	  break;
-	case 'b':
-	  c2 = '\b';
-	  break;
-	case 'f':
-	  c2 = '\f';
-	  break;
-	case '\\':
-	case '(':
-	case ')':
-	  c2 = c;
-	  break;
-	case '0': case '1': case '2': case '3':
-	case '4': case '5': case '6': case '7':
-	  c2 = c - '0';
-	  c = lookChar();
-	  if (c >= '0' && c <= '7') {
-	    getChar();
-	    c2 = (c2 << 3) + (c - '0');
-	    c = lookChar();
-	    if (c >= '0' && c <= '7') {
-	      getChar();
-	      c2 = (c2 << 3) + (c - '0');
-	    }
-	  }
-	  break;
-	case '\r':
-	  c = lookChar();
-	  if (c == '\n') {
-	    getChar();
-	  }
-	  break;
-	case '\n':
-	  break;
-	case EOF:
-	  error(errSyntaxError, getPos(), "Unterminated string");
-	  done = gTrue;
-	  break;
-	default:
-	  c2 = c;
-	  break;
-	}
-	break;
-
-      default:
-	c2 = c;
-	break;
-      }
-
-      if (c2 != EOF) {
-	if (n == tokBufSize) {
-	  if (!s)
-	    s = new GooString(tokBuf, tokBufSize);
-	  else
-	    s->append(tokBuf, tokBufSize);
-	  p = tokBuf;
-	  n = 0;
-	  
-	  // we are growing see if the document is not malformed and we are growing too much
-	  if (objNum > 0 && xref != NULL)
-	  {
-	    int newObjNum = xref->getNumEntry(curStr.streamGetPos());
-	    if (newObjNum != objNum)
-	    {
-	      error(errSyntaxError, getPos(), "Unterminated string");
-	      done = gTrue;
-	      delete s;
-	      n = -2;
-	    }
-	  }
-	}
-	*p++ = (char)c2;
-	++n;
-      }
-    } while (!done);
-    if (n >= 0) {
-      if (!s)
-        s = new GooString(tokBuf, n);
-      else
-        s->append(tokBuf, n);
-      return Object(s);
-    } else {
-      return Object(objEOF);
-    }
-    break;
-
-  // name
-  case '/':
-    p = tokBuf;
-    n = 0;
-    s = NULL;
-    while ((c = lookChar()) != EOF && !specialChars[c]) {
-      getChar();
-      if (c == '#') {
-	c2 = lookChar();
-	if (c2 >= '0' && c2 <= '9') {
-	  c = c2 - '0';
-	} else if (c2 >= 'A' && c2 <= 'F') {
-	  c = c2 - 'A' + 10;
-	} else if (c2 >= 'a' && c2 <= 'f') {
-	  c = c2 - 'a' + 10;
-	} else {
-	  goto notEscChar;
-	}
-	getChar();
-	c <<= 4;
-	c2 = getChar();
-	if (c2 >= '0' && c2 <= '9') {
-	  c += c2 - '0';
-	} else if (c2 >= 'A' && c2 <= 'F') {
-	  c += c2 - 'A' + 10;
-	} else if (c2 >= 'a' && c2 <= 'f') {
-	  c += c2 - 'a' + 10;
-	} else {
-	  error(errSyntaxError, getPos(), "Illegal digit in hex char in name");
-	}
-      }
-     notEscChar:
-      // the PDF spec claims that names are limited to 127 chars, but
-      // Distiller 8 will produce longer names, and Acrobat 8 will
-      // accept longer names
-      ++n;
-      if (n < tokBufSize) {
-	*p++ = c;
-      } else if (n == tokBufSize) {
-	error(errSyntaxError, getPos(), "Warning: name token is longer than what the specification says it can be");
-	*p = c;
-	s = new GooString(tokBuf, n);
-      } else {
-	s->append((char)c);
-      }
-    }
-    if (n < tokBufSize) {
-      *p = '\0';
-      return Object(objName, tokBuf);
-    } else {
-      Object obj(objName, s->getCString());
-      delete s;
-      return obj;
-    }
-    break;
-
-  // array punctuation
-  case '[':
-  case ']':
-    tokBuf[0] = c;
-    tokBuf[1] = '\0';
-    return Object(objCmd, tokBuf);
-    break;
-
-  // hex string or dict punctuation
-  case '<':
-    c = lookChar();
-
-    // dict punctuation
-    if (c == '<') {
-      getChar();
-      tokBuf[0] = tokBuf[1] = '<';
-      tokBuf[2] = '\0';
-      return Object(objCmd, tokBuf);
-
-    // hex string
-    } else {
-      p = tokBuf;
-      m = n = 0;
-      c2 = 0;
-      s = NULL;
-      while (1) {
-	c = getChar();
-	if (c == '>') {
-	  break;
-	} else if (c == EOF) {
-	  error(errSyntaxError, getPos(), "Unterminated hex string");
-	  break;
-	} else if (specialChars[c] != 1) {
-	  c2 = c2 << 4;
-	  if (c >= '0' && c <= '9')
-	    c2 += c - '0';
-	  else if (c >= 'A' && c <= 'F')
-	    c2 += c - 'A' + 10;
-	  else if (c >= 'a' && c <= 'f')
-	    c2 += c - 'a' + 10;
-	  else
-	    error(errSyntaxError, getPos(), "Illegal character <{0:02x}> in hex string", c);
-	  if (++m == 2) {
-	    if (n == tokBufSize) {
-	      if (!s)
-		s = new GooString(tokBuf, tokBufSize);
-	      else
-		s->append(tokBuf, tokBufSize);
-	      p = tokBuf;
-	      n = 0;
-	    }
-	    *p++ = (char)c2;
-	    ++n;
-	    c2 = 0;
-	    m = 0;
-	  }
-	}
-      }
-      if (!s)
-	s = new GooString(tokBuf, n);
-      else
-	s->append(tokBuf, n);
-      if (m == 1)
-	s->append((char)(c2 << 4));
-      return Object(s);
-    }
-    break;
-
-  // dict punctuation
-  case '>':
-    c = lookChar();
-    if (c == '>') {
-      getChar();
-      tokBuf[0] = tokBuf[1] = '>';
-      tokBuf[2] = '\0';
-      return Object(objCmd, tokBuf);
-    } else {
-      error(errSyntaxError, getPos(), "Illegal character '>'");
-      return Object(objError);
-    }
-    break;
-
-  // error
-  case ')':
-  case '{':
-  case '}':
-    error(errSyntaxError, getPos(), "Illegal character '{0:c}'", c);
-    return Object(objError);
-    break;
-
-  // command
-  default:
-    p = tokBuf;
-    *p++ = c;
-    n = 1;
-    while ((c = lookChar()) != EOF && !specialChars[c]) {
-      getChar();
-      if (++n == tokBufSize) {
-	error(errSyntaxError, getPos(), "Command token too long");
-	break;
-      }
-      *p++ = c;
-    }
-    *p = '\0';
-    if (tokBuf[0] == 't' && !strcmp(tokBuf, "true")) {
-      return Object(gTrue);
-    } else if (tokBuf[0] == 'f' && !strcmp(tokBuf, "false")) {
-      return Object(gFalse);
-    } else if (tokBuf[0] == 'n' && !strcmp(tokBuf, "null")) {
-      return Object(objNull);
-    } else {
-      return Object(objCmd, tokBuf);
-    }
-    break;
-  }
-
-  return Object();
-}
-
-Object Lexer::getObj(const char *cmdA, int objNum) {
-  char *p;
-  int c;
-  GBool comment;
-  int n;
-
-  // skip whitespace and comments
-  comment = gFalse;
-  const char *cmd1 = tokBuf;
-  *tokBuf = 0;
-  while (strcmp(cmdA, cmd1) && (objNum < 0 || (xref && xref->getNumEntry(getPos()) == objNum))) {
-    while (1) {
-      if ((c = getChar()) == EOF) {
-        return Object(objEOF);
-      }
-      if (comment) {
-        if (c == '\r' || c == '\n') {
-          comment = gFalse;
-        }
-      } else if (c == '%') {
-        comment = gTrue;
-      } else if (specialChars[c] != 1) {
-        break;
-      }
-    }
-    p = tokBuf;
-    *p++ = c;
-    n = 1;
-    while ((c = lookChar()) != EOF && specialChars[c] == 0) {
-      getChar();
-      if (++n == tokBufSize) {
-        break;
-      }
-      *p++ = c;
-    }
-    *p = '\0';
-  }
-
-  return Object(objCmd, tokBuf);
-}
-
-void Lexer::skipToNextLine() {
-  int c;
-
-  while (1) {
-    c = getChar();
-    if (c == EOF || c == '\n') {
-      return;
-    }
-    if (c == '\r') {
-      if ((c = lookChar()) == '\n') {
-	getChar();
-      }
-      return;
-    }
-  }
-}
-
-GBool Lexer::isSpace(int c) {
-  return c >= 0 && c <= 0xff && specialChars[c] == 1;
-}
diff --git a/source/libs/poppler/poppler-src/poppler/Object.h.orig b/source/libs/poppler/poppler-src/poppler/Object.h.orig
deleted file mode 100644
index f2ca20d15..000000000
--- a/source/libs/poppler/poppler-src/poppler/Object.h.orig
+++ /dev/null
@@ -1,416 +0,0 @@
-//========================================================================
-//
-// Object.h
-//
-// Copyright 1996-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-//========================================================================
-//
-// Modified under the Poppler project - http://poppler.freedesktop.org
-//
-// All changes made under the Poppler project to this file are licensed
-// under GPL version 2 or later
-//
-// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
-// Copyright (C) 2008 Kees Cook <kees@outflux.net>
-// Copyright (C) 2008, 2010, 2017 Albert Astals Cid <aacid@kde.org>
-// Copyright (C) 2009 Jakub Wilk <jwilk@jwilk.net>
-// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
-// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
-// Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com>
-// Copyright (C) 2013 Adrian Perez de Castro <aperez@igalia.com>
-// Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
-//
-// To see a description of the changes please see the Changelog file that
-// came with your tarball or type make ChangeLog if you are building from git
-//
-//========================================================================
-
-#ifndef OBJECT_H
-#define OBJECT_H
-
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
-#include <set>
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
-#include "goo/gtypes.h"
-#include "goo/gmem.h"
-#include "goo/GooString.h"
-#include "goo/GooLikely.h"
-#include "Error.h"
-
-#define OBJECT_TYPE_CHECK(wanted_type) \
-    if (unlikely(type != wanted_type)) { \
-        error(errInternal, 0, "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(errInternal, 0, "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(); \
-    }
-
-#define OBJECT_3TYPES_CHECK(wanted_type1, wanted_type2, wanted_type3)	\
-    if (unlikely(type != wanted_type1) && unlikely(type != wanted_type2) && unlikely(type != wanted_type3)) { \
-        error(errInternal, 0, "Call to Object where the object was type {0:d}, " \
-	      "not the expected type {1:d}, {2:d} or {3:d}", type, wanted_type1, wanted_type2, wanted_type3); \
-        abort(); \
-    }
-
-#define CHECK_NOT_DEAD \
-  if (unlikely(type == objDead)) { \
-        error(errInternal, 0, "Call to dead object"); \
-        abort(); \
-    }
-
-class XRef;
-class Array;
-class Dict;
-class Stream;
-
-//------------------------------------------------------------------------
-// Ref
-//------------------------------------------------------------------------
-
-struct Ref {
-  int num;			// object number
-  int gen;			// generation number
-};
-
-//------------------------------------------------------------------------
-// object types
-//------------------------------------------------------------------------
-
-enum ObjType {
-  // simple objects
-  objBool,			// boolean
-  objInt,			// integer
-  objReal,			// real
-  objString,			// string
-  objName,			// name
-  objNull,			// null
-
-  // complex objects
-  objArray,			// array
-  objDict,			// dictionary
-  objStream,			// stream
-  objRef,			// indirect reference
-
-  // special objects
-  objCmd,			// command name
-  objError,			// error return from Lexer
-  objEOF,			// end of file return from Lexer
-  objNone,			// uninitialized object
-
-  // poppler-only objects
-  objInt64,			// integer with at least 64-bits
-  objDead			// and object after shallowCopy
-};
-
-#define numObjTypes 16		// total number of object types
-
-//------------------------------------------------------------------------
-// Object
-//------------------------------------------------------------------------
-
-#ifdef DEBUG_MEM
-#define initObj(t) free(); zeroUnion(); ++numAlloc[type = t]
-#else
-#define initObj(t) free(); zeroUnion(); type = t
-#endif
-
-#ifdef DEBUG_MEM
-#define constructObj(t) ++numAlloc[type = t]
-#else
-#define constructObj(t) type = t
-#endif
-
-class Object {
-public:
-  // clear the anonymous union as best we can -- clear at least a pointer
-  void zeroUnion() { this->cString = NULL; }
-
-  // Default constructor.
-  Object():
-    type(objNone) { zeroUnion(); }
-  ~Object();
-
-  explicit Object(GBool boolnA)
-    { constructObj(objBool); booln = boolnA; }
-  explicit Object(int intgA)
-    { constructObj(objInt); intg = intgA; }
-  explicit Object(ObjType typeA)
-    { constructObj(typeA); }
-  explicit Object(double realA)
-    { constructObj(objReal); real = realA; }
-  explicit Object(GooString *stringA)
-    { constructObj(objString); string = stringA; }
-  Object(ObjType typeA, const char *stringA)
-    { constructObj(typeA); cString = copyString(stringA); }
-  explicit Object(long long int64gA)
-    { constructObj(objInt64); int64g = int64gA; }
-  explicit Object(Array *arrayA)
-    { constructObj(objArray); array = arrayA; }
-  explicit Object(Dict *dictA)
-    { constructObj(objDict); dict = dictA; }
-  explicit Object(Stream *streamA)
-    { constructObj(objStream); stream = streamA; }
-  Object(int numA, int genA)
-    { constructObj(objRef); ref.num = numA; ref.gen = genA; }
-  template<typename T> Object(T) = delete;
-
-  Object(Object&& other);
-  Object& operator=(Object&& other);
-
-  Object &operator=(const Object &other) = delete;
-  Object(const Object &other) = delete;
-
-  // Set object to null.
-  void setToNull() { initObj(objNull); }
-
-  // Copy this to obj
-  Object copy() const;
-
-  // If object is a Ref, fetch and return the referenced object.
-  // Otherwise, return a copy of the object.
-  Object fetch(XRef *xref, int recursion = 0) const;
-
-  // Type checking.
-  ObjType getType() const { CHECK_NOT_DEAD; return type; }
-  GBool isBool() const { CHECK_NOT_DEAD; return type == objBool; }
-  GBool isInt() const { CHECK_NOT_DEAD; return type == objInt; }
-  GBool isReal() const { CHECK_NOT_DEAD; return type == objReal; }
-  GBool isNum() const { CHECK_NOT_DEAD; return type == objInt || type == objReal || type == objInt64; }
-  GBool isString() const { CHECK_NOT_DEAD; return type == objString; }
-  GBool isName() const { CHECK_NOT_DEAD; return type == objName; }
-  GBool isNull() const { CHECK_NOT_DEAD; return type == objNull; }
-  GBool isArray() const { CHECK_NOT_DEAD; return type == objArray; }
-  GBool isDict() const { CHECK_NOT_DEAD; return type == objDict; }
-  GBool isStream() const { CHECK_NOT_DEAD; return type == objStream; }
-  GBool isRef() const { CHECK_NOT_DEAD; return type == objRef; }
-  GBool isCmd() const { CHECK_NOT_DEAD; return type == objCmd; }
-  GBool isError() const { CHECK_NOT_DEAD; return type == objError; }
-  GBool isEOF() const { CHECK_NOT_DEAD; return type == objEOF; }
-  GBool isNone() const { CHECK_NOT_DEAD; return type == objNone; }
-  GBool isInt64() const { CHECK_NOT_DEAD; return type == objInt64; }
-  GBool isIntOrInt64() const { CHECK_NOT_DEAD; return type == objInt || type == objInt64; }
-
-  // Special type checking.
-  GBool isName(const char *nameA) const
-    { return type == objName && !strcmp(cString, nameA); }
-  GBool isDict(const char *dictType) const;
-  GBool isStream(char *dictType) const;
-  GBool isCmd(const char *cmdA) const
-    { return type == objCmd && !strcmp(cString, cmdA); }
-
-  // Accessors.
-  GBool getBool() const { OBJECT_TYPE_CHECK(objBool); return booln; }
-  int getInt() const { OBJECT_TYPE_CHECK(objInt); return intg; }
-  double getReal() const { OBJECT_TYPE_CHECK(objReal); return real; }
-
-  // Note: integers larger than 2^53 can not be exactly represented by a double.
-  // Where the exact value of integers up to 2^63 is required, use isInt64()/getInt64().
-  double getNum() const { OBJECT_3TYPES_CHECK(objInt, objInt64, objReal);
-    return type == objInt ? (double)intg : type == objInt64 ? (double)int64g : real; }
-  double getNum(bool *ok) const {
-    if (unlikely(type != objInt && type != objInt64 && type != objReal)) {
-      *ok = false;
-      return 0.;
-    }
-    return type == objInt ? (double)intg : type == objInt64 ? (double)int64g : real;
-  }
-  GooString *getString() const { OBJECT_TYPE_CHECK(objString); return string; }
-  // After takeString() the only method that should be called for the object is free()
-  // because the object it's not expected to have a NULL string.
-  GooString *takeString() {
-    OBJECT_TYPE_CHECK(objString); GooString *s = string; string = NULL; return s; }
-  char *getName() const { OBJECT_TYPE_CHECK(objName); return cString; }
-  Array *getArray() const { OBJECT_TYPE_CHECK(objArray); return array; }
-  Dict *getDict() const { OBJECT_TYPE_CHECK(objDict); return dict; }
-  Stream *getStream() const { OBJECT_TYPE_CHECK(objStream); return stream; }
-  Ref getRef() const { OBJECT_TYPE_CHECK(objRef); return ref; }
-  int getRefNum() const { OBJECT_TYPE_CHECK(objRef); return ref.num; }
-  int getRefGen() const { OBJECT_TYPE_CHECK(objRef); return ref.gen; }
-  char *getCmd() const { OBJECT_TYPE_CHECK(objCmd); return cString; }
-  long long getInt64() const { OBJECT_TYPE_CHECK(objInt64); return int64g; }
-  long long getIntOrInt64() const { OBJECT_2TYPES_CHECK(objInt, objInt64);
-    return type == objInt ? intg : int64g; }
-
-  // Array accessors.
-  int arrayGetLength() const;
-  void arrayAdd(Object &&elem);
-  void arrayRemove(int i);
-  Object arrayGet(int i, int recursion) const;
-  Object arrayGetNF(int i) const;
-
-  // Dict accessors.
-  int dictGetLength() const;
-  void dictAdd(char *key, Object &&val);
-  void dictSet(const char *key, Object &&val);
-  void dictRemove(const char *key);
-  GBool dictIs(const char *dictType) const;
-  Object dictLookup(const char *key, int recursion = 0) const;
-  Object dictLookupNF(const char *key) const;
-  char *dictGetKey(int i) const;
-  Object dictGetVal(int i) const;
-  Object dictGetValNF(int i) const;
-
-  // Stream accessors.
-  GBool streamIs(char *dictType) const;
-  void streamReset();
-  void streamClose();
-  int streamGetChar() const;
-  int streamGetChars(int nChars, Guchar *buffer) const;
-  int streamLookChar() const;
-  char *streamGetLine(char *buf, int size) const;
-  Goffset streamGetPos() const;
-  void streamSetPos(Goffset pos, int dir = 0);
-  Dict *streamGetDict() const;
-
-  // Output.
-  const char *getTypeName() const;
-  void print(FILE *f = stdout) const;
-
-  // Memory testing.
-  static void memCheck(FILE *f);
-
-private:
-  friend class Array; // Needs free and initNullAfterMalloc
-  friend class Dict; // Needs free and initNullAfterMalloc
-  friend class XRef; // Needs free and initNullAfterMalloc
-
-  // Free object contents.
-  void free();
-
-  // Only use if are mallocing Objects
-  void initNullAfterMalloc() { constructObj(objNull); }
-
-  ObjType type;			// object type
-  union {			// value for each type:
-    GBool booln;		//   boolean
-    int intg;			//   integer
-    long long int64g;           //   64-bit integer
-    double real;		//   real
-    GooString *string;		//   string
-    char *cString;		//   name or command, depending on objType
-    Array *array;		//   array
-    Dict *dict;			//   dictionary
-    Stream *stream;		//   stream
-    Ref ref;			//   indirect reference
-  };
-
-#ifdef DEBUG_MEM
-  static int			// number of each type of object
-    numAlloc[numObjTypes];	//   currently allocated
-#endif
-};
-
-//------------------------------------------------------------------------
-// Array accessors.
-//------------------------------------------------------------------------
-
-#include "Array.h"
-
-inline int Object::arrayGetLength() const
-  { OBJECT_TYPE_CHECK(objArray); return array->getLength(); }
-
-inline void Object::arrayAdd(Object &&elem)
-  { OBJECT_TYPE_CHECK(objArray); array->add(std::move(elem)); }
-
-inline void Object::arrayRemove(int i)
-  { OBJECT_TYPE_CHECK(objArray); array->remove(i); }
-
-inline Object Object::arrayGet(int i, int recursion = 0) const
-  { OBJECT_TYPE_CHECK(objArray); return array->get(i, recursion); }
-
-inline Object Object::arrayGetNF(int i) const
-  { OBJECT_TYPE_CHECK(objArray); return array->getNF(i); }
-
-//------------------------------------------------------------------------
-// Dict accessors.
-//------------------------------------------------------------------------
-
-#include "Dict.h"
-
-inline int Object::dictGetLength() const
-  { OBJECT_TYPE_CHECK(objDict); return dict->getLength(); }
-
-inline void Object::dictAdd(char *key, Object &&val)
-  { OBJECT_TYPE_CHECK(objDict); dict->add(key, std::move(val)); }
-
-inline void Object::dictSet(const char *key, Object &&val)
-  { OBJECT_TYPE_CHECK(objDict); dict->set(key, std::move(val)); }
-
-inline void Object::dictRemove(const char *key)
-  { OBJECT_TYPE_CHECK(objDict); dict->remove(key); }
-
-inline GBool Object::dictIs(const char *dictType) const
-  { OBJECT_TYPE_CHECK(objDict); return dict->is(dictType); }
-
-inline GBool Object::isDict(const char *dictType) const
-  { return type == objDict && dictIs(dictType); }
-
-inline Object Object::dictLookup(const char *key, int recursion) const
-  { OBJECT_TYPE_CHECK(objDict); return dict->lookup(key, recursion); }
-
-inline Object Object::dictLookupNF(const char *key) const
-  { OBJECT_TYPE_CHECK(objDict); return dict->lookupNF(key); }
-
-inline char *Object::dictGetKey(int i) const
-  { OBJECT_TYPE_CHECK(objDict); return dict->getKey(i); }
-
-inline Object Object::dictGetVal(int i) const
-  { OBJECT_TYPE_CHECK(objDict); return dict->getVal(i); }
-
-inline Object Object::dictGetValNF(int i) const
-  { OBJECT_TYPE_CHECK(objDict); return dict->getValNF(i); }
-
-//------------------------------------------------------------------------
-// Stream accessors.
-//------------------------------------------------------------------------
-
-#include "Stream.h"
-
-inline GBool Object::streamIs(char *dictType) const
-  { OBJECT_TYPE_CHECK(objStream); return stream->getDict()->is(dictType); }
-
-inline GBool Object::isStream(char *dictType) const
-  { return type == objStream && streamIs(dictType); }
-
-inline void Object::streamReset()
-  { OBJECT_TYPE_CHECK(objStream); stream->reset(); }
-
-inline void Object::streamClose()
-  { OBJECT_TYPE_CHECK(objStream); stream->close(); }
-
-inline int Object::streamGetChar() const
-  { OBJECT_TYPE_CHECK(objStream); return stream->getChar(); }
-
-inline int Object::streamGetChars(int nChars, Guchar *buffer) const
-  { OBJECT_TYPE_CHECK(objStream); return stream->doGetChars(nChars, buffer); }
-
-inline int Object::streamLookChar() const
-  { OBJECT_TYPE_CHECK(objStream); return stream->lookChar(); }
-
-inline char *Object::streamGetLine(char *buf, int size) const
-  { OBJECT_TYPE_CHECK(objStream); return stream->getLine(buf, size); }
-
-inline Goffset Object::streamGetPos() const
-  { OBJECT_TYPE_CHECK(objStream); return stream->getPos(); }
-
-inline void Object::streamSetPos(Goffset pos, int dir)
-  { OBJECT_TYPE_CHECK(objStream); stream->setPos(pos, dir); }
-
-inline Dict *Object::streamGetDict() const
-  { OBJECT_TYPE_CHECK(objStream); return stream->getDict(); }
-
-#endif
diff --git a/source/libs/poppler/poppler-src/poppler/Object.h~ b/source/libs/poppler/poppler-src/poppler/Object.h~
deleted file mode 100644
index f2ca20d15..000000000
--- a/source/libs/poppler/poppler-src/poppler/Object.h~
+++ /dev/null
@@ -1,416 +0,0 @@
-//========================================================================
-//
-// Object.h
-//
-// Copyright 1996-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-//========================================================================
-//
-// Modified under the Poppler project - http://poppler.freedesktop.org
-//
-// All changes made under the Poppler project to this file are licensed
-// under GPL version 2 or later
-//
-// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
-// Copyright (C) 2008 Kees Cook <kees@outflux.net>
-// Copyright (C) 2008, 2010, 2017 Albert Astals Cid <aacid@kde.org>
-// Copyright (C) 2009 Jakub Wilk <jwilk@jwilk.net>
-// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
-// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
-// Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com>
-// Copyright (C) 2013 Adrian Perez de Castro <aperez@igalia.com>
-// Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
-//
-// To see a description of the changes please see the Changelog file that
-// came with your tarball or type make ChangeLog if you are building from git
-//
-//========================================================================
-
-#ifndef OBJECT_H
-#define OBJECT_H
-
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
-#include <set>
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
-#include "goo/gtypes.h"
-#include "goo/gmem.h"
-#include "goo/GooString.h"
-#include "goo/GooLikely.h"
-#include "Error.h"
-
-#define OBJECT_TYPE_CHECK(wanted_type) \
-    if (unlikely(type != wanted_type)) { \
-        error(errInternal, 0, "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(errInternal, 0, "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(); \
-    }
-
-#define OBJECT_3TYPES_CHECK(wanted_type1, wanted_type2, wanted_type3)	\
-    if (unlikely(type != wanted_type1) && unlikely(type != wanted_type2) && unlikely(type != wanted_type3)) { \
-        error(errInternal, 0, "Call to Object where the object was type {0:d}, " \
-	      "not the expected type {1:d}, {2:d} or {3:d}", type, wanted_type1, wanted_type2, wanted_type3); \
-        abort(); \
-    }
-
-#define CHECK_NOT_DEAD \
-  if (unlikely(type == objDead)) { \
-        error(errInternal, 0, "Call to dead object"); \
-        abort(); \
-    }
-
-class XRef;
-class Array;
-class Dict;
-class Stream;
-
-//------------------------------------------------------------------------
-// Ref
-//------------------------------------------------------------------------
-
-struct Ref {
-  int num;			// object number
-  int gen;			// generation number
-};
-
-//------------------------------------------------------------------------
-// object types
-//------------------------------------------------------------------------
-
-enum ObjType {
-  // simple objects
-  objBool,			// boolean
-  objInt,			// integer
-  objReal,			// real
-  objString,			// string
-  objName,			// name
-  objNull,			// null
-
-  // complex objects
-  objArray,			// array
-  objDict,			// dictionary
-  objStream,			// stream
-  objRef,			// indirect reference
-
-  // special objects
-  objCmd,			// command name
-  objError,			// error return from Lexer
-  objEOF,			// end of file return from Lexer
-  objNone,			// uninitialized object
-
-  // poppler-only objects
-  objInt64,			// integer with at least 64-bits
-  objDead			// and object after shallowCopy
-};
-
-#define numObjTypes 16		// total number of object types
-
-//------------------------------------------------------------------------
-// Object
-//------------------------------------------------------------------------
-
-#ifdef DEBUG_MEM
-#define initObj(t) free(); zeroUnion(); ++numAlloc[type = t]
-#else
-#define initObj(t) free(); zeroUnion(); type = t
-#endif
-
-#ifdef DEBUG_MEM
-#define constructObj(t) ++numAlloc[type = t]
-#else
-#define constructObj(t) type = t
-#endif
-
-class Object {
-public:
-  // clear the anonymous union as best we can -- clear at least a pointer
-  void zeroUnion() { this->cString = NULL; }
-
-  // Default constructor.
-  Object():
-    type(objNone) { zeroUnion(); }
-  ~Object();
-
-  explicit Object(GBool boolnA)
-    { constructObj(objBool); booln = boolnA; }
-  explicit Object(int intgA)
-    { constructObj(objInt); intg = intgA; }
-  explicit Object(ObjType typeA)
-    { constructObj(typeA); }
-  explicit Object(double realA)
-    { constructObj(objReal); real = realA; }
-  explicit Object(GooString *stringA)
-    { constructObj(objString); string = stringA; }
-  Object(ObjType typeA, const char *stringA)
-    { constructObj(typeA); cString = copyString(stringA); }
-  explicit Object(long long int64gA)
-    { constructObj(objInt64); int64g = int64gA; }
-  explicit Object(Array *arrayA)
-    { constructObj(objArray); array = arrayA; }
-  explicit Object(Dict *dictA)
-    { constructObj(objDict); dict = dictA; }
-  explicit Object(Stream *streamA)
-    { constructObj(objStream); stream = streamA; }
-  Object(int numA, int genA)
-    { constructObj(objRef); ref.num = numA; ref.gen = genA; }
-  template<typename T> Object(T) = delete;
-
-  Object(Object&& other);
-  Object& operator=(Object&& other);
-
-  Object &operator=(const Object &other) = delete;
-  Object(const Object &other) = delete;
-
-  // Set object to null.
-  void setToNull() { initObj(objNull); }
-
-  // Copy this to obj
-  Object copy() const;
-
-  // If object is a Ref, fetch and return the referenced object.
-  // Otherwise, return a copy of the object.
-  Object fetch(XRef *xref, int recursion = 0) const;
-
-  // Type checking.
-  ObjType getType() const { CHECK_NOT_DEAD; return type; }
-  GBool isBool() const { CHECK_NOT_DEAD; return type == objBool; }
-  GBool isInt() const { CHECK_NOT_DEAD; return type == objInt; }
-  GBool isReal() const { CHECK_NOT_DEAD; return type == objReal; }
-  GBool isNum() const { CHECK_NOT_DEAD; return type == objInt || type == objReal || type == objInt64; }
-  GBool isString() const { CHECK_NOT_DEAD; return type == objString; }
-  GBool isName() const { CHECK_NOT_DEAD; return type == objName; }
-  GBool isNull() const { CHECK_NOT_DEAD; return type == objNull; }
-  GBool isArray() const { CHECK_NOT_DEAD; return type == objArray; }
-  GBool isDict() const { CHECK_NOT_DEAD; return type == objDict; }
-  GBool isStream() const { CHECK_NOT_DEAD; return type == objStream; }
-  GBool isRef() const { CHECK_NOT_DEAD; return type == objRef; }
-  GBool isCmd() const { CHECK_NOT_DEAD; return type == objCmd; }
-  GBool isError() const { CHECK_NOT_DEAD; return type == objError; }
-  GBool isEOF() const { CHECK_NOT_DEAD; return type == objEOF; }
-  GBool isNone() const { CHECK_NOT_DEAD; return type == objNone; }
-  GBool isInt64() const { CHECK_NOT_DEAD; return type == objInt64; }
-  GBool isIntOrInt64() const { CHECK_NOT_DEAD; return type == objInt || type == objInt64; }
-
-  // Special type checking.
-  GBool isName(const char *nameA) const
-    { return type == objName && !strcmp(cString, nameA); }
-  GBool isDict(const char *dictType) const;
-  GBool isStream(char *dictType) const;
-  GBool isCmd(const char *cmdA) const
-    { return type == objCmd && !strcmp(cString, cmdA); }
-
-  // Accessors.
-  GBool getBool() const { OBJECT_TYPE_CHECK(objBool); return booln; }
-  int getInt() const { OBJECT_TYPE_CHECK(objInt); return intg; }
-  double getReal() const { OBJECT_TYPE_CHECK(objReal); return real; }
-
-  // Note: integers larger than 2^53 can not be exactly represented by a double.
-  // Where the exact value of integers up to 2^63 is required, use isInt64()/getInt64().
-  double getNum() const { OBJECT_3TYPES_CHECK(objInt, objInt64, objReal);
-    return type == objInt ? (double)intg : type == objInt64 ? (double)int64g : real; }
-  double getNum(bool *ok) const {
-    if (unlikely(type != objInt && type != objInt64 && type != objReal)) {
-      *ok = false;
-      return 0.;
-    }
-    return type == objInt ? (double)intg : type == objInt64 ? (double)int64g : real;
-  }
-  GooString *getString() const { OBJECT_TYPE_CHECK(objString); return string; }
-  // After takeString() the only method that should be called for the object is free()
-  // because the object it's not expected to have a NULL string.
-  GooString *takeString() {
-    OBJECT_TYPE_CHECK(objString); GooString *s = string; string = NULL; return s; }
-  char *getName() const { OBJECT_TYPE_CHECK(objName); return cString; }
-  Array *getArray() const { OBJECT_TYPE_CHECK(objArray); return array; }
-  Dict *getDict() const { OBJECT_TYPE_CHECK(objDict); return dict; }
-  Stream *getStream() const { OBJECT_TYPE_CHECK(objStream); return stream; }
-  Ref getRef() const { OBJECT_TYPE_CHECK(objRef); return ref; }
-  int getRefNum() const { OBJECT_TYPE_CHECK(objRef); return ref.num; }
-  int getRefGen() const { OBJECT_TYPE_CHECK(objRef); return ref.gen; }
-  char *getCmd() const { OBJECT_TYPE_CHECK(objCmd); return cString; }
-  long long getInt64() const { OBJECT_TYPE_CHECK(objInt64); return int64g; }
-  long long getIntOrInt64() const { OBJECT_2TYPES_CHECK(objInt, objInt64);
-    return type == objInt ? intg : int64g; }
-
-  // Array accessors.
-  int arrayGetLength() const;
-  void arrayAdd(Object &&elem);
-  void arrayRemove(int i);
-  Object arrayGet(int i, int recursion) const;
-  Object arrayGetNF(int i) const;
-
-  // Dict accessors.
-  int dictGetLength() const;
-  void dictAdd(char *key, Object &&val);
-  void dictSet(const char *key, Object &&val);
-  void dictRemove(const char *key);
-  GBool dictIs(const char *dictType) const;
-  Object dictLookup(const char *key, int recursion = 0) const;
-  Object dictLookupNF(const char *key) const;
-  char *dictGetKey(int i) const;
-  Object dictGetVal(int i) const;
-  Object dictGetValNF(int i) const;
-
-  // Stream accessors.
-  GBool streamIs(char *dictType) const;
-  void streamReset();
-  void streamClose();
-  int streamGetChar() const;
-  int streamGetChars(int nChars, Guchar *buffer) const;
-  int streamLookChar() const;
-  char *streamGetLine(char *buf, int size) const;
-  Goffset streamGetPos() const;
-  void streamSetPos(Goffset pos, int dir = 0);
-  Dict *streamGetDict() const;
-
-  // Output.
-  const char *getTypeName() const;
-  void print(FILE *f = stdout) const;
-
-  // Memory testing.
-  static void memCheck(FILE *f);
-
-private:
-  friend class Array; // Needs free and initNullAfterMalloc
-  friend class Dict; // Needs free and initNullAfterMalloc
-  friend class XRef; // Needs free and initNullAfterMalloc
-
-  // Free object contents.
-  void free();
-
-  // Only use if are mallocing Objects
-  void initNullAfterMalloc() { constructObj(objNull); }
-
-  ObjType type;			// object type
-  union {			// value for each type:
-    GBool booln;		//   boolean
-    int intg;			//   integer
-    long long int64g;           //   64-bit integer
-    double real;		//   real
-    GooString *string;		//   string
-    char *cString;		//   name or command, depending on objType
-    Array *array;		//   array
-    Dict *dict;			//   dictionary
-    Stream *stream;		//   stream
-    Ref ref;			//   indirect reference
-  };
-
-#ifdef DEBUG_MEM
-  static int			// number of each type of object
-    numAlloc[numObjTypes];	//   currently allocated
-#endif
-};
-
-//------------------------------------------------------------------------
-// Array accessors.
-//------------------------------------------------------------------------
-
-#include "Array.h"
-
-inline int Object::arrayGetLength() const
-  { OBJECT_TYPE_CHECK(objArray); return array->getLength(); }
-
-inline void Object::arrayAdd(Object &&elem)
-  { OBJECT_TYPE_CHECK(objArray); array->add(std::move(elem)); }
-
-inline void Object::arrayRemove(int i)
-  { OBJECT_TYPE_CHECK(objArray); array->remove(i); }
-
-inline Object Object::arrayGet(int i, int recursion = 0) const
-  { OBJECT_TYPE_CHECK(objArray); return array->get(i, recursion); }
-
-inline Object Object::arrayGetNF(int i) const
-  { OBJECT_TYPE_CHECK(objArray); return array->getNF(i); }
-
-//------------------------------------------------------------------------
-// Dict accessors.
-//------------------------------------------------------------------------
-
-#include "Dict.h"
-
-inline int Object::dictGetLength() const
-  { OBJECT_TYPE_CHECK(objDict); return dict->getLength(); }
-
-inline void Object::dictAdd(char *key, Object &&val)
-  { OBJECT_TYPE_CHECK(objDict); dict->add(key, std::move(val)); }
-
-inline void Object::dictSet(const char *key, Object &&val)
-  { OBJECT_TYPE_CHECK(objDict); dict->set(key, std::move(val)); }
-
-inline void Object::dictRemove(const char *key)
-  { OBJECT_TYPE_CHECK(objDict); dict->remove(key); }
-
-inline GBool Object::dictIs(const char *dictType) const
-  { OBJECT_TYPE_CHECK(objDict); return dict->is(dictType); }
-
-inline GBool Object::isDict(const char *dictType) const
-  { return type == objDict && dictIs(dictType); }
-
-inline Object Object::dictLookup(const char *key, int recursion) const
-  { OBJECT_TYPE_CHECK(objDict); return dict->lookup(key, recursion); }
-
-inline Object Object::dictLookupNF(const char *key) const
-  { OBJECT_TYPE_CHECK(objDict); return dict->lookupNF(key); }
-
-inline char *Object::dictGetKey(int i) const
-  { OBJECT_TYPE_CHECK(objDict); return dict->getKey(i); }
-
-inline Object Object::dictGetVal(int i) const
-  { OBJECT_TYPE_CHECK(objDict); return dict->getVal(i); }
-
-inline Object Object::dictGetValNF(int i) const
-  { OBJECT_TYPE_CHECK(objDict); return dict->getValNF(i); }
-
-//------------------------------------------------------------------------
-// Stream accessors.
-//------------------------------------------------------------------------
-
-#include "Stream.h"
-
-inline GBool Object::streamIs(char *dictType) const
-  { OBJECT_TYPE_CHECK(objStream); return stream->getDict()->is(dictType); }
-
-inline GBool Object::isStream(char *dictType) const
-  { return type == objStream && streamIs(dictType); }
-
-inline void Object::streamReset()
-  { OBJECT_TYPE_CHECK(objStream); stream->reset(); }
-
-inline void Object::streamClose()
-  { OBJECT_TYPE_CHECK(objStream); stream->close(); }
-
-inline int Object::streamGetChar() const
-  { OBJECT_TYPE_CHECK(objStream); return stream->getChar(); }
-
-inline int Object::streamGetChars(int nChars, Guchar *buffer) const
-  { OBJECT_TYPE_CHECK(objStream); return stream->doGetChars(nChars, buffer); }
-
-inline int Object::streamLookChar() const
-  { OBJECT_TYPE_CHECK(objStream); return stream->lookChar(); }
-
-inline char *Object::streamGetLine(char *buf, int size) const
-  { OBJECT_TYPE_CHECK(objStream); return stream->getLine(buf, size); }
-
-inline Goffset Object::streamGetPos() const
-  { OBJECT_TYPE_CHECK(objStream); return stream->getPos(); }
-
-inline void Object::streamSetPos(Goffset pos, int dir)
-  { OBJECT_TYPE_CHECK(objStream); stream->setPos(pos, dir); }
-
-inline Dict *Object::streamGetDict() const
-  { OBJECT_TYPE_CHECK(objStream); return stream->getDict(); }
-
-#endif
diff --git a/source/libs/poppler/poppler-src/poppler/PDFDoc.cc.orig b/source/libs/poppler/poppler-src/poppler/PDFDoc.cc.orig
deleted file mode 100644
index 90f039d8e..000000000
--- a/source/libs/poppler/poppler-src/poppler/PDFDoc.cc.orig
+++ /dev/null
@@ -1,1985 +0,0 @@
-//========================================================================
-//
-// PDFDoc.cc
-//
-// Copyright 1996-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-//========================================================================
-//
-// Modified under the Poppler project - http://poppler.freedesktop.org
-//
-// All changes made under the Poppler project to this file are licensed
-// under GPL version 2 or later
-//
-// Copyright (C) 2005, 2006, 2008 Brad Hards <bradh@frogmouth.net>
-// Copyright (C) 2005, 2007-2009, 2011-2017 Albert Astals Cid <aacid@kde.org>
-// Copyright (C) 2008 Julien Rebetez <julienr@svn.gnome.org>
-// Copyright (C) 2008, 2010 Pino Toscano <pino@kde.org>
-// Copyright (C) 2008, 2010, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
-// Copyright (C) 2009 Eric Toombs <ewtoombs@uwaterloo.ca>
-// Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
-// Copyright (C) 2009, 2011 Axel Struebing <axel.struebing@freenet.de>
-// Copyright (C) 2010-2012, 2014 Hib Eris <hib@hiberis.nl>
-// Copyright (C) 2010 Jakub Wilk <jwilk@jwilk.net>
-// Copyright (C) 2010 Ilya Gorenbein <igorenbein@finjan.com>
-// Copyright (C) 2010 Srinivas Adicherla <srinivas.adicherla@geodesic.com>
-// Copyright (C) 2010 Philip Lorenz <lorenzph+freedesktop@gmail.com>
-// Copyright (C) 2011-2016 Thomas Freitag <Thomas.Freitag@alfa.de>
-// Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
-// Copyright (C) 2013, 2014, 2017 Adrian Johnson <ajohnson@redneon.com>
-// Copyright (C) 2013 Adam Reichold <adamreichold@myopera.com>
-// Copyright (C) 2014 Bogdan Cristea <cristeab@gmail.com>
-// Copyright (C) 2015 Li Junling <lijunling@sina.com>
-// Copyright (C) 2015 André Guerreiro <aguerreiro1985@gmail.com>
-// Copyright (C) 2015 André Esser <bepandre@hotmail.com>
-// Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
-// Copyright (C) 2017 Jean Ghali <jghali@libertysurf.fr>
-//
-// To see a description of the changes please see the Changelog file that
-// came with your tarball or type make ChangeLog if you are building from git
-//
-//========================================================================
-
-#include <config.h>
-#include <poppler-config.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include <ctype.h>
-#include <locale.h>
-#include <stdio.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <time.h>
-#include <sys/stat.h>
-#include "goo/glibc.h"
-#include "goo/gstrtod.h"
-#include "goo/GooString.h"
-#include "goo/gfile.h"
-#include "poppler-config.h"
-#include "GlobalParams.h"
-#include "Page.h"
-#include "Catalog.h"
-#include "Stream.h"
-#include "XRef.h"
-#include "Linearization.h"
-#include "Link.h"
-#include "OutputDev.h"
-#include "Error.h"
-#include "ErrorCodes.h"
-#include "Lexer.h"
-#include "Parser.h"
-#include "SecurityHandler.h"
-#include "Decrypt.h"
-#ifndef DISABLE_OUTLINE
-#include "Outline.h"
-#endif
-#include "PDFDoc.h"
-#include "Hints.h"
-#include "UTF.h"
-
-#ifdef MULTITHREADED
-#  define pdfdocLocker()   MutexLocker locker(&mutex)
-#else
-#  define pdfdocLocker()
-#endif
-
-//------------------------------------------------------------------------
-
-#define headerSearchSize 1024	// read this many bytes at beginning of
-				//   file to look for '%PDF'
-#define pdfIdLength 32   // PDF Document IDs (PermanentId, UpdateId) length
-
-#define linearizationSearchSize 1024	// read this many bytes at beginning of
-					// file to look for linearization
-					// dictionary
-
-#define xrefSearchSize 1024	// read this many bytes at end of file
-				//   to look for 'startxref'
-
-//------------------------------------------------------------------------
-// PDFDoc
-//------------------------------------------------------------------------
-
-void PDFDoc::init()
-{
-#ifdef MULTITHREADED
-  gInitMutex(&mutex);
-#endif
-  ok = gFalse;
-  errCode = errNone;
-  fileName = NULL;
-  file = NULL;
-  str = NULL;
-  xref = NULL;
-  linearization = NULL;
-  catalog = NULL;
-  hints = NULL;
-#ifndef DISABLE_OUTLINE
-  outline = NULL;
-#endif
-  startXRefPos = -1;
-  secHdlr = NULL;
-  pageCache = NULL;
-}
-
-PDFDoc::PDFDoc()
-{
-  init();
-}
-
-PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword,
-	       GooString *userPassword, void *guiDataA) {
-#ifdef _WIN32
-  int n, i;
-#endif
-
-  init();
-
-  fileName = fileNameA;
-  guiData = guiDataA;
-#ifdef _WIN32
-  n = fileName->getLength();
-  fileNameU = (wchar_t *)gmallocn(n + 1, sizeof(wchar_t));
-  for (i = 0; i < n; ++i) {
-    fileNameU[i] = (wchar_t)(fileName->getChar(i) & 0xff);
-  }
-  fileNameU[n] = L'\0';
-#endif
-
-  // try to open file
-#ifdef _WIN32
-  wchar_t *wFileName = (wchar_t*)utf8ToUtf16(fileName->getCString());
-  file = GooFile::open(wFileName);
-  gfree(wFileName);
-#else
-   file = GooFile::open(fileName);
-#endif
-  if (file == NULL) {
-    // fopen() has failed.
-    // Keep a copy of the errno returned by fopen so that it can be 
-    // referred to later.
-    fopenErrno = errno;
-    error(errIO, -1, "Couldn't open file '{0:t}': {1:s}.", fileName, strerror(errno));
-    errCode = errOpenFile;
-    return;
-  }
-
-  // create stream
-  str = new FileStream(file, 0, gFalse, file->size(), Object(objNull));
-
-  ok = setup(ownerPassword, userPassword);
-}
-
-#ifdef _WIN32
-PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword,
-	       GooString *userPassword, void *guiDataA) {
-  OSVERSIONINFO version;
-  int i;
-
-  init();
-
-  guiData = guiDataA;
-
-  // save both Unicode and 8-bit copies of the file name
-  fileName = new GooString();
-  fileNameU = (wchar_t *)gmallocn(fileNameLen + 1, sizeof(wchar_t));
-  for (i = 0; i < fileNameLen; ++i) {
-    fileName->append((char)fileNameA[i]);
-    fileNameU[i] = fileNameA[i];
-  }
-  fileNameU[fileNameLen] = L'\0';
-  
-  // try to open file
-  // NB: _wfopen is only available in NT
-  version.dwOSVersionInfoSize = sizeof(version);
-  GetVersionEx(&version);
-  if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-    file = GooFile::open(fileNameU);
-  } else {
-    file = GooFile::open(fileName);
-  }
-  if (!file) {
-    error(errIO, -1, "Couldn't open file '{0:t}'", fileName);
-    errCode = errOpenFile;
-    return;
-  }
-
-  // create stream
-  str = new FileStream(file, 0, gFalse, file->size(), Object(objNull));
-
-  ok = setup(ownerPassword, userPassword);
-}
-#endif
-
-PDFDoc::PDFDoc(BaseStream *strA, GooString *ownerPassword,
-	       GooString *userPassword, void *guiDataA) {
-#ifdef _WIN32
-  int n, i;
-#endif
-
-  init();
-  guiData = guiDataA;
-  if (strA->getFileName()) {
-    fileName = strA->getFileName()->copy();
-#ifdef _WIN32
-    n = fileName->getLength();
-    fileNameU = (wchar_t *)gmallocn(n + 1, sizeof(wchar_t));
-    for (i = 0; i < n; ++i) {
-      fileNameU[i] = (wchar_t)(fileName->getChar(i) & 0xff);
-    }
-    fileNameU[n] = L'\0';
-#endif
-  } else {
-    fileName = NULL;
-#ifdef _WIN32
-    fileNameU = NULL;
-#endif
-  }
-  str = strA;
-  ok = setup(ownerPassword, userPassword);
-}
-
-GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) {
-  pdfdocLocker();
-  str->setPos(0, -1);
-  if (str->getPos() < 0)
-  {
-    error(errSyntaxError, -1, "Document base stream is not seekable");
-    return gFalse;
-  }
-
-  str->reset();
-
-  // check footer
-  // Adobe does not seem to enforce %%EOF, so we do the same
-//  if (!checkFooter()) return gFalse;
-  
-  // check header
-  checkHeader();
-
-  GBool wasReconstructed = false;
-
-  // read xref table
-  xref = new XRef(str, getStartXRef(), getMainXRefEntriesOffset(), &wasReconstructed);
-  if (!xref->isOk()) {
-    if (wasReconstructed) {
-      delete xref;
-      startXRefPos = -1;
-      xref = new XRef(str, getStartXRef(gTrue), getMainXRefEntriesOffset(gTrue), &wasReconstructed);
-    }
-    if (!xref->isOk()) {
-      error(errSyntaxError, -1, "Couldn't read xref table");
-      errCode = xref->getErrorCode();
-      return gFalse;
-    }
-  }
-
-  // check for encryption
-  if (!checkEncryption(ownerPassword, userPassword)) {
-    errCode = errEncrypted;
-    return gFalse;
-  }
-
-  // read catalog
-  catalog = new Catalog(this);
-  if (catalog && !catalog->isOk()) {
-    if (!wasReconstructed)
-    {
-      // try one more time to contruct the Catalog, maybe the problem is damaged XRef 
-      delete catalog;
-      delete xref;
-      xref = new XRef(str, 0, 0, NULL, true);
-      catalog = new Catalog(this);
-    }
-
-    if (catalog && !catalog->isOk()) {
-      error(errSyntaxError, -1, "Couldn't read page catalog");
-      errCode = errBadCatalog;
-      return gFalse;
-    }
-  }
-
-  // done
-  return gTrue;
-}
-
-PDFDoc::~PDFDoc() {
-  if (pageCache) {
-    for (int i = 0; i < getNumPages(); i++) {
-      if (pageCache[i]) {
-        delete pageCache[i];
-      }
-    }
-    gfree(pageCache);
-  }
-  delete secHdlr;
-#ifndef DISABLE_OUTLINE
-  if (outline) {
-    delete outline;
-  }
-#endif
-  if (catalog) {
-    delete catalog;
-  }
-  if (xref) {
-    delete xref;
-  }
-  if (hints) {
-    delete hints;
-  }
-  if (linearization) {
-    delete linearization;
-  }
-  if (str) {
-    delete str;
-  }
-  if (file) {
-    delete file;
-  }
-  if (fileName) {
-    delete fileName;
-  }
-#ifdef _WIN32
-  if (fileNameU) {
-    gfree(fileNameU);
-  }
-#endif
-#ifdef MULTITHREADED
-  gDestroyMutex(&mutex);
-#endif
-}
-
-
-// Check for a %%EOF at the end of this stream
-GBool PDFDoc::checkFooter() {
-  // we look in the last 1024 chars because Adobe does the same
-  char *eof = new char[1025];
-  Goffset pos = str->getPos();
-  str->setPos(1024, -1);
-  int i, ch;
-  for (i = 0; i < 1024; i++)
-  {
-    ch = str->getChar();
-    if (ch == EOF)
-      break;
-    eof[i] = ch;
-  }
-  eof[i] = '\0';
-
-  bool found = false;
-  for (i = i - 5; i >= 0; i--) {
-    if (strncmp (&eof[i], "%%EOF", 5) == 0) {
-      found = true;
-      break;
-    }
-  }
-  if (!found)
-  {
-    error(errSyntaxError, -1, "Document has not the mandatory ending %%EOF");
-    errCode = errDamaged;
-    delete[] eof;
-    return gFalse;
-  }
-  delete[] eof;
-  str->setPos(pos);
-  return gTrue;
-}
-  
-// Check for a PDF header on this stream.  Skip past some garbage
-// if necessary.
-void PDFDoc::checkHeader() {
-  char hdrBuf[headerSearchSize+1];
-  char *p;
-  char *tokptr;
-  int i;
-
-  pdfMajorVersion = 0;
-  pdfMinorVersion = 0;
-  for (i = 0; i < headerSearchSize; ++i) {
-    hdrBuf[i] = str->getChar();
-  }
-  hdrBuf[headerSearchSize] = '\0';
-  for (i = 0; i < headerSearchSize - 5; ++i) {
-    if (!strncmp(&hdrBuf[i], "%PDF-", 5)) {
-      break;
-    }
-  }
-  if (i >= headerSearchSize - 5) {
-    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(errSyntaxWarning, -1, "May not be a PDF file (continuing anyway)");
-    return;
-  }
-  sscanf(p, "%d.%d", &pdfMajorVersion, &pdfMinorVersion);
-  // We don't do the version check. Don't add it back in.
-}
-
-GBool PDFDoc::checkEncryption(GooString *ownerPassword, GooString *userPassword) {
-  GBool encrypted;
-  GBool ret;
-
-  Object encrypt = xref->getTrailerDict()->dictLookup("Encrypt");
-  if ((encrypted = encrypt.isDict())) {
-    if ((secHdlr = SecurityHandler::make(this, &encrypt))) {
-      if (secHdlr->isUnencrypted()) {
-	// no encryption
-	ret = gTrue;
-      } else if (secHdlr->checkEncryption(ownerPassword, userPassword)) {
-	// authorization succeeded
-       	xref->setEncryption(secHdlr->getPermissionFlags(),
-			    secHdlr->getOwnerPasswordOk(),
-			    secHdlr->getFileKey(),
-			    secHdlr->getFileKeyLength(),
-			    secHdlr->getEncVersion(),
-			    secHdlr->getEncRevision(),
-			    secHdlr->getEncAlgorithm());
-	ret = gTrue;
-      } else {
-	// authorization failed
-	ret = gFalse;
-      }
-    } else {
-      // couldn't find the matching security handler
-      ret = gFalse;
-    }
-  } else {
-    // document is not encrypted
-    ret = gTrue;
-  }
-  return ret;
-}
-
-std::vector<FormWidgetSignature*> PDFDoc::getSignatureWidgets()
-{
-  int num_pages = getNumPages();
-  FormPageWidgets *page_widgets = NULL;
-  std::vector<FormWidgetSignature*> widget_vector;
-
-  for (int i = 1; i <= num_pages; i++) {
-    Page *p = getCatalog()->getPage(i);
-    if (p) {
-      page_widgets = p->getFormWidgets();
-      for (int j = 0; page_widgets != NULL && j < page_widgets->getNumWidgets(); j++) {
-	if (page_widgets->getWidget(j)->getType() == formSignature) {
-	    widget_vector.push_back(static_cast<FormWidgetSignature*>(page_widgets->getWidget(j)));
-	}
-      }
-      delete page_widgets;
-    }
-  }
-  return widget_vector;
-}
-
-void PDFDoc::displayPage(OutputDev *out, int page,
-			 double hDPI, double vDPI, int rotate,
-			 GBool useMediaBox, GBool crop, GBool printing,
-			 GBool (*abortCheckCbk)(void *data),
-			 void *abortCheckCbkData,
-                         GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
-                         void *annotDisplayDecideCbkData, GBool copyXRef) {
-  if (globalParams->getPrintCommands()) {
-    printf("***** page %d *****\n", page);
-  }
-
-  if (getPage(page))
-    getPage(page)->display(out, hDPI, vDPI,
-				    rotate, useMediaBox, crop, printing,
-				    abortCheckCbk, abortCheckCbkData,
-				    annotDisplayDecideCbk, annotDisplayDecideCbkData, copyXRef);
-
-}
-
-void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage,
-			  double hDPI, double vDPI, int rotate,
-			  GBool useMediaBox, GBool crop, GBool printing,
-			  GBool (*abortCheckCbk)(void *data),
-			  void *abortCheckCbkData,
-                          GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
-                          void *annotDisplayDecideCbkData) {
-  int page;
-
-  for (page = firstPage; page <= lastPage; ++page) {
-    displayPage(out, page, hDPI, vDPI, rotate, useMediaBox, crop, printing,
-		abortCheckCbk, abortCheckCbkData,
-                annotDisplayDecideCbk, annotDisplayDecideCbkData);
-  }
-}
-
-void PDFDoc::displayPageSlice(OutputDev *out, int page,
-			      double hDPI, double vDPI, int rotate,
-			      GBool useMediaBox, GBool crop, GBool printing,
-			      int sliceX, int sliceY, int sliceW, int sliceH,
-			      GBool (*abortCheckCbk)(void *data),
-			      void *abortCheckCbkData,
-                              GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
-                              void *annotDisplayDecideCbkData, GBool copyXRef) {
-  if (getPage(page))
-    getPage(page)->displaySlice(out, hDPI, vDPI,
-					 rotate, useMediaBox, crop,
-					 sliceX, sliceY, sliceW, sliceH,
-					 printing,
-					 abortCheckCbk, abortCheckCbkData,
-					 annotDisplayDecideCbk, annotDisplayDecideCbkData, copyXRef);
-}
-
-Links *PDFDoc::getLinks(int page) {
-  Page *p = getPage(page);
-  if (!p) {
-    return new Links (NULL);
-  }
-  return p->getLinks();
-}
-
-void PDFDoc::processLinks(OutputDev *out, int page) {
-  if (getPage(page))
-    getPage(page)->processLinks(out);
-}
-
-Linearization *PDFDoc::getLinearization()
-{
-  if (!linearization) {
-    linearization = new Linearization(str);
-    linearizationState = 0;
-  }
-  return linearization;
-}
-
-GBool PDFDoc::checkLinearization() {
-  if (linearization == NULL)
-    return gFalse;
-  if (linearizationState == 1)
-    return gTrue;
-  if (linearizationState == 2)
-    return gFalse;
-  if (!hints) {
-    hints = new Hints(str, linearization, getXRef(), secHdlr);
-  }
-  if (!hints->isOk()) {
-    linearizationState = 2;
-    return gFalse;
-  }
-  for (int page = 1; page <= linearization->getNumPages(); page++) {
-    Ref pageRef;
-
-    pageRef.num = hints->getPageObjectNum(page);
-    if (!pageRef.num) {
-      linearizationState = 2;
-      return gFalse;
-    }
-
-    // check for bogus ref - this can happen in corrupted PDF files
-    if (pageRef.num < 0 || pageRef.num >= xref->getNumObjects()) {
-      linearizationState = 2;
-      return gFalse;
-    }
-
-    pageRef.gen = xref->getEntry(pageRef.num)->gen;
-    Object obj = xref->fetch(pageRef.num, pageRef.gen);
-    if (!obj.isDict("Page")) {
-      linearizationState = 2;
-      return gFalse;
-    }
-  }
-  linearizationState = 1;
-  return gTrue;
-}
-
-GBool PDFDoc::isLinearized(GBool tryingToReconstruct) {
-  if ((str->getLength()) &&
-      (getLinearization()->getLength() == str->getLength()))
-    return gTrue;
-  else {
-    if (tryingToReconstruct)
-      return getLinearization()->getLength() > 0;
-    else
-      return gFalse;
-  }
-}
-
-void PDFDoc::setDocInfoModified(Object *infoObj)
-{
-  Object infoObjRef = getDocInfoNF();
-  xref->setModifiedObject(infoObj, infoObjRef.getRef());
-}
-
-void PDFDoc::setDocInfoStringEntry(const char *key, GooString *value)
-{
-  GBool removeEntry = !value || value->getLength() == 0 || value->hasJustUnicodeMarker();
-  if (removeEntry) {
-    delete value;
-  }
-
-  Object infoObj = getDocInfo();
-  if (infoObj.isNull() && removeEntry) {
-    // No info dictionary, so no entry to remove.
-    return;
-  }
-
-  infoObj = createDocInfoIfNoneExists();
-  if (removeEntry) {
-    infoObj.dictSet(key, Object(objNull));
-  } else {
-    infoObj.dictSet(key, Object(value));
-  }
-
-
-  if (infoObj.dictGetLength() == 0) {
-    // Info dictionary is empty. Remove it altogether.
-    removeDocInfo();
-  } else {
-    setDocInfoModified(&infoObj);
-  }
-}
-
-GooString *PDFDoc::getDocInfoStringEntry(const char *key) {
-  Object infoObj = getDocInfo();
-  if (!infoObj.isDict()) {
-      return NULL;
-  }
-
-  Object entryObj = infoObj.dictLookup(key);
-
-  GooString *result;
-
-  if (entryObj.isString()) {
-    result = entryObj.takeString();
-  } else {
-    result = NULL;
-  }
-
-  return result;
-}
-
-static GBool
-get_id (GooString *encodedidstring, GooString *id) {
-  const char *encodedid = encodedidstring->getCString();
-  char pdfid[pdfIdLength + 1];
-  int n;
-
-  if (encodedidstring->getLength() != pdfIdLength / 2)
-    return gFalse;
-
-  n = sprintf(pdfid, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
-	      encodedid[0] & 0xff, encodedid[1] & 0xff, encodedid[2] & 0xff, encodedid[3] & 0xff,
-	      encodedid[4] & 0xff, encodedid[5] & 0xff, encodedid[6] & 0xff, encodedid[7] & 0xff,
-	      encodedid[8] & 0xff, encodedid[9] & 0xff, encodedid[10] & 0xff, encodedid[11] & 0xff,
-	      encodedid[12] & 0xff, encodedid[13] & 0xff, encodedid[14] & 0xff, encodedid[15] & 0xff);
-  if (n != pdfIdLength)
-    return gFalse;
-
-  id->Set(pdfid, pdfIdLength);
-  return gTrue;
-}
-
-GBool PDFDoc::getID(GooString *permanent_id, GooString *update_id) {
-  Object obj = xref->getTrailerDict()->dictLookup ("ID");
-
-  if (obj.isArray() && obj.arrayGetLength() == 2) {
-    if (permanent_id) {
-      Object obj2 = obj.arrayGet(0);
-      if (obj2.isString()) {
-        if (!get_id (obj2.getString(), permanent_id)) {
-	  return gFalse;
-	}
-      } else {
-        error(errSyntaxError, -1, "Invalid permanent ID");
-	return gFalse;
-      }
-    }
-
-    if (update_id) {
-      Object obj2 = obj.arrayGet(1);
-      if (obj2.isString()) {
-        if (!get_id (obj2.getString(), update_id)) {
-	  return gFalse;
-	}
-      } else {
-        error(errSyntaxError, -1, "Invalid update ID");
-	return gFalse;
-      }
-    }
-
-    return gTrue;
-  }
-
-  return gFalse;
-}
-
-Hints *PDFDoc::getHints()
-{
-  if (!hints && isLinearized()) {
-    hints = new Hints(str, getLinearization(), getXRef(), secHdlr);
-  }
-
-  return hints;
-}
-
-int PDFDoc::savePageAs(GooString *name, int pageNo) 
-{
-  FILE *f;
-  OutStream *outStr;
-  XRef *yRef, *countRef;
-  int rootNum = getXRef()->getNumObjects() + 1;
-
-  // Make sure that special flags are set, because we are going to read
-  // all objects, including Unencrypted ones.
-  xref->scanSpecialFlags();
-
-  Guchar *fileKey;
-  CryptAlgorithm encAlgorithm;
-  int keyLength;
-  xref->getEncryptionParameters(&fileKey, &encAlgorithm, &keyLength);
-
-  if (pageNo < 1 || pageNo > getNumPages() || !getCatalog()->getPage(pageNo)) {
-    error(errInternal, -1, "Illegal pageNo: {0:d}({1:d})", pageNo, getNumPages() );
-    return errOpenFile;
-  }
-  PDFRectangle *cropBox = NULL;
-  if (getCatalog()->getPage(pageNo)->isCropped()) {
-    cropBox = getCatalog()->getPage(pageNo)->getCropBox();
-  }
-  replacePageDict(pageNo, 
-    getCatalog()->getPage(pageNo)->getRotate(),
-    getCatalog()->getPage(pageNo)->getMediaBox(),
-    cropBox);
-  Ref *refPage = getCatalog()->getPageRef(pageNo);
-  Object page = getXRef()->fetch(refPage->num, refPage->gen);
-
-  if (!(f = fopen(name->getCString(), "wb"))) {
-    error(errIO, -1, "Couldn't open file '{0:t}'", name);
-    return errOpenFile;
-  }
-  outStr = new FileOutStream(f,0);
-
-  yRef = new XRef(getXRef()->getTrailerDict());
-
-  if (secHdlr != NULL && !secHdlr->isUnencrypted()) {
-    yRef->setEncryption(secHdlr->getPermissionFlags(), 
-      secHdlr->getOwnerPasswordOk(), fileKey, keyLength, secHdlr->getEncVersion(), secHdlr->getEncRevision(), encAlgorithm);
-  }
-  countRef = new XRef();
-  Object *trailerObj = getXRef()->getTrailerDict();
-  if (trailerObj->isDict()) {
-    markPageObjects(trailerObj->getDict(), yRef, countRef, 0, refPage->num, rootNum + 2);
-  }
-  yRef->add(0, 65535, 0, gFalse);
-  writeHeader(outStr, getPDFMajorVersion(), getPDFMinorVersion());
-
-  // get and mark info dict
-  Object infoObj = getXRef()->getDocInfo();
-  if (infoObj.isDict()) {
-    Dict *infoDict = infoObj.getDict();
-    markPageObjects(infoDict, yRef, countRef, 0, refPage->num, rootNum + 2);
-    if (trailerObj->isDict()) {
-      Dict *trailerDict = trailerObj->getDict();
-      Object ref = trailerDict->lookupNF("Info");
-      if (ref.isRef()) {
-        yRef->add(ref.getRef().num, ref.getRef().gen, 0, gTrue);
-        if (getXRef()->getEntry(ref.getRef().num)->type == xrefEntryCompressed) {
-          yRef->getEntry(ref.getRef().num)->type = xrefEntryCompressed;
-        }
-      }
-    }
-  }
-  
-  // get and mark output intents etc.
-  Object catObj = getXRef()->getCatalog();
-  Dict *catDict = catObj.getDict();
-  Object pagesObj = catDict->lookup("Pages");
-  Object afObj = catDict->lookupNF("AcroForm");
-  if (!afObj.isNull()) {
-    markAcroForm(&afObj, yRef, countRef, 0, refPage->num, rootNum + 2);
-  }
-  Dict *pagesDict = pagesObj.getDict();
-  Object resourcesObj = pagesDict->lookup("Resources");
-  if (resourcesObj.isDict())
-    markPageObjects(resourcesObj.getDict(), yRef, countRef, 0, refPage->num, rootNum + 2);
-  markPageObjects(catDict, yRef, countRef, 0, refPage->num, rootNum + 2);
-
-  Dict *pageDict = page.getDict();
-  if (resourcesObj.isNull() && !pageDict->hasKey("Resources")) {
-    Object *resourceDictObject = getCatalog()->getPage(pageNo)->getResourceDictObject();
-    if (resourceDictObject->isDict()) {
-      resourcesObj = resourceDictObject->copy();
-      markPageObjects(resourcesObj.getDict(), yRef, countRef, 0, refPage->num, rootNum + 2);
-    }
-  }
-  markPageObjects(pageDict, yRef, countRef, 0, refPage->num, rootNum + 2);
-  Object annotsObj = pageDict->lookupNF("Annots");
-  if (!annotsObj.isNull()) {
-    markAnnotations(&annotsObj, yRef, countRef, 0, refPage->num, rootNum + 2);
-  }
-  yRef->markUnencrypted();
-  writePageObjects(outStr, yRef, 0);
-
-  yRef->add(rootNum,0,outStr->getPos(),gTrue);
-  outStr->printf("%d 0 obj\n", rootNum);
-  outStr->printf("<< /Type /Catalog /Pages %d 0 R", rootNum + 1); 
-  for (int j = 0; j < catDict->getLength(); j++) {
-    const char *key = catDict->getKey(j);
-    if (strcmp(key, "Type") != 0 &&
-      strcmp(key, "Catalog") != 0 &&
-      strcmp(key, "Pages") != 0) 
-    {
-      if (j > 0) outStr->printf(" ");
-      Object value = catDict->getValNF(j);
-      outStr->printf("/%s ", key);
-      writeObject(&value, outStr, getXRef(), 0, NULL, cryptRC4, 0, 0, 0);
-    }
-  }
-  outStr->printf(">>\nendobj\n");
-
-  yRef->add(rootNum + 1,0,outStr->getPos(),gTrue);
-  outStr->printf("%d 0 obj\n", rootNum + 1);
-  outStr->printf("<< /Type /Pages /Kids [ %d 0 R ] /Count 1 ", rootNum + 2);
-  if (resourcesObj.isDict()) {
-    outStr->printf("/Resources ");
-    writeObject(&resourcesObj, outStr, getXRef(), 0, NULL, cryptRC4, 0, 0, 0);
-  }
-  outStr->printf(">>\n");
-  outStr->printf("endobj\n");
-
-  yRef->add(rootNum + 2,0,outStr->getPos(),gTrue);
-  outStr->printf("%d 0 obj\n", rootNum + 2);
-  outStr->printf("<< ");
-  for (int n = 0; n < pageDict->getLength(); n++) {
-    if (n > 0) outStr->printf(" ");
-    const char *key = pageDict->getKey(n);
-    Object value = pageDict->getValNF(n);
-    if (strcmp(key, "Parent") == 0) {
-      outStr->printf("/Parent %d 0 R", rootNum + 1);
-    } else {
-      outStr->printf("/%s ", key);
-      writeObject(&value, outStr, getXRef(), 0, NULL, cryptRC4, 0, 0, 0);
-    }
-  }
-  outStr->printf(" >>\nendobj\n");
-
-  Goffset uxrefOffset = outStr->getPos();
-  Ref ref;
-  ref.num = rootNum;
-  ref.gen = 0;
-  Object trailerDict = createTrailerDict(rootNum + 3, gFalse, 0, &ref, getXRef(),
-                                        name->getCString(), uxrefOffset);
-  writeXRefTableTrailer(std::move(trailerDict), yRef, gFalse /* do not write unnecessary entries */,
-                        uxrefOffset, outStr, getXRef());
-
-  outStr->close();
-  fclose(f);
-  delete yRef;
-  delete countRef;
-  delete outStr;
-
-  return errNone;
-}
-
-int PDFDoc::saveAs(GooString *name, PDFWriteMode mode) {
-  FILE *f;
-  OutStream *outStr;
-  int res;
-
-  if (!(f = fopen(name->getCString(), "wb"))) {
-    error(errIO, -1, "Couldn't open file '{0:t}'", name);
-    return errOpenFile;
-  }
-  outStr = new FileOutStream(f,0);
-  res = saveAs(outStr, mode);
-  delete outStr;
-  fclose(f);
-  return res;
-}
-
-int PDFDoc::saveAs(OutStream *outStr, PDFWriteMode mode) {
-  if (!xref->isModified() && mode == writeStandard) {
-    // simply copy the original file
-    saveWithoutChangesAs (outStr);
-  } else if (mode == writeForceRewrite) {
-    saveCompleteRewrite(outStr);
-  } else {
-    saveIncrementalUpdate(outStr);
-  }
-
-  return errNone;
-}
-
-int PDFDoc::saveWithoutChangesAs(GooString *name) {
-  FILE *f;
-  OutStream *outStr;
-  int res;
-
-  if (!(f = fopen(name->getCString(), "wb"))) {
-    error(errIO, -1, "Couldn't open file '{0:t}'", name);
-    return errOpenFile;
-  }
-  
-  outStr = new FileOutStream(f,0);
-  res = saveWithoutChangesAs(outStr);
-  delete outStr;
-
-  fclose(f);
-
-  return res;
-}
-
-int PDFDoc::saveWithoutChangesAs(OutStream *outStr) {
-  int c;
-  
-  BaseStream *copyStr = str->copy();
-  copyStr->reset();
-  while ((c = copyStr->getChar()) != EOF) {
-    outStr->put(c);
-  }
-  copyStr->close();
-  delete copyStr;
-
-  return errNone;
-}
-
-void PDFDoc::saveIncrementalUpdate (OutStream* outStr)
-{
-  XRef *uxref;
-  int c;
-  //copy the original file
-  BaseStream *copyStr = str->copy();
-  copyStr->reset();
-  while ((c = copyStr->getChar()) != EOF) {
-    outStr->put(c);
-  }
-  copyStr->close();
-  delete copyStr;
-
-  Guchar *fileKey;
-  CryptAlgorithm encAlgorithm;
-  int keyLength;
-  xref->getEncryptionParameters(&fileKey, &encAlgorithm, &keyLength);
-
-  uxref = new XRef();
-  uxref->add(0, 65535, 0, gFalse);
-  xref->lock();
-  for(int i=0; i<xref->getNumObjects(); i++) {
-    if ((xref->getEntry(i)->type == xrefEntryFree) && 
-        (xref->getEntry(i)->gen == 0)) //we skip the irrelevant free objects
-      continue;
-
-    if (xref->getEntry(i)->getFlag(XRefEntry::Updated)) { //we have an updated object
-      Ref ref;
-      ref.num = i;
-      ref.gen = xref->getEntry(i)->type == xrefEntryCompressed ? 0 : xref->getEntry(i)->gen;
-      if (xref->getEntry(i)->type != xrefEntryFree) {
-        Object obj1 = xref->fetch(ref.num, ref.gen, 1);
-        Goffset offset = writeObjectHeader(&ref, outStr);
-        writeObject(&obj1, outStr, fileKey, encAlgorithm, keyLength, ref.num, ref.gen);
-        writeObjectFooter(outStr);
-        uxref->add(ref.num, ref.gen, offset, gTrue);
-      } else {
-        uxref->add(ref.num, ref.gen, 0, gFalse);
-      }
-    }
-  }
-  xref->unlock();
-  // because of "uxref->add(0, 65535, 0, gFalse);" uxref->getNumObjects() will
-  // always be >= 1; if it is 1, it means there is nothing to update
-  if (uxref->getNumObjects() == 1) {
-    delete uxref;
-    return;
-  }
-
-  Goffset uxrefOffset = outStr->getPos();
-  int numobjects = xref->getNumObjects();
-  const char *fileNameA = fileName ? fileName->getCString() : NULL;
-  Ref rootRef, uxrefStreamRef;
-  rootRef.num = getXRef()->getRootNum();
-  rootRef.gen = getXRef()->getRootGen();
-
-  // Output a xref stream if there is a xref stream already
-  GBool xRefStream = xref->isXRefStream();
-
-  if (xRefStream) {
-    // Append an entry for the xref stream itself
-    uxrefStreamRef.num = numobjects++;
-    uxrefStreamRef.gen = 0;
-    uxref->add(uxrefStreamRef.num, uxrefStreamRef.gen, uxrefOffset, gTrue);
-  }
-
-  Object trailerDict = createTrailerDict(numobjects, gTrue, getStartXRef(), &rootRef, getXRef(), fileNameA, uxrefOffset);
-  if (xRefStream) {
-    writeXRefStreamTrailer(std::move(trailerDict), uxref, &uxrefStreamRef, uxrefOffset, outStr, getXRef());
-  } else {
-    writeXRefTableTrailer(std::move(trailerDict), uxref, gFalse, uxrefOffset, outStr, getXRef());
-  }
-
-  delete uxref;
-}
-
-void PDFDoc::saveCompleteRewrite (OutStream* outStr)
-{
-  // Make sure that special flags are set, because we are going to read
-  // all objects, including Unencrypted ones.
-  xref->scanSpecialFlags();
-
-  Guchar *fileKey;
-  CryptAlgorithm encAlgorithm;
-  int keyLength;
-  xref->getEncryptionParameters(&fileKey, &encAlgorithm, &keyLength);
-
-  outStr->printf("%%PDF-%d.%d\r\n",pdfMajorVersion,pdfMinorVersion);
-  XRef *uxref = new XRef();
-  uxref->add(0, 65535, 0, gFalse);
-  xref->lock();
-  for(int i=0; i<xref->getNumObjects(); i++) {
-    Ref ref;
-    XRefEntryType type = xref->getEntry(i)->type;
-    if (type == xrefEntryFree) {
-      ref.num = i;
-      ref.gen = xref->getEntry(i)->gen;
-      /* the XRef class adds a lot of irrelevant free entries, we only want the significant one
-          and we don't want the one with num=0 because it has already been added (gen = 65535)*/
-      if (ref.gen > 0 && ref.num > 0)
-        uxref->add(ref.num, ref.gen, 0, gFalse);
-    } else if (xref->getEntry(i)->getFlag(XRefEntry::DontRewrite)) {
-      // This entry must not be written, put a free entry instead (with incremented gen)
-      ref.num = i;
-      ref.gen = xref->getEntry(i)->gen + 1;
-      uxref->add(ref.num, ref.gen, 0, gFalse);
-    } else if (type == xrefEntryUncompressed){ 
-      ref.num = i;
-      ref.gen = xref->getEntry(i)->gen;
-      Object obj1 = xref->fetch(ref.num, ref.gen, 1);
-      Goffset offset = writeObjectHeader(&ref, outStr);
-      // Write unencrypted objects in unencrypted form
-      if (xref->getEntry(i)->getFlag(XRefEntry::Unencrypted)) {
-        writeObject(&obj1, outStr, NULL, cryptRC4, 0, 0, 0);
-      } else {
-        writeObject(&obj1, outStr, fileKey, encAlgorithm, keyLength, ref.num, ref.gen);
-      }
-      writeObjectFooter(outStr);
-      uxref->add(ref.num, ref.gen, offset, gTrue);
-    } else if (type == xrefEntryCompressed) {
-      ref.num = i;
-      ref.gen = 0; //compressed entries have gen == 0
-      Object obj1 = xref->fetch(ref.num, ref.gen, 1);
-      Goffset offset = writeObjectHeader(&ref, outStr);
-      writeObject(&obj1, outStr, fileKey, encAlgorithm, keyLength, ref.num, ref.gen);
-      writeObjectFooter(outStr);
-      uxref->add(ref.num, ref.gen, offset, gTrue);
-    }
-  }
-  xref->unlock();
-  Goffset uxrefOffset = outStr->getPos();
-  writeXRefTableTrailer(uxrefOffset, uxref, gTrue /* write all entries */,
-                        uxref->getNumObjects(), outStr, gFalse /* complete rewrite */);
-  delete uxref;
-}
-
-void PDFDoc::writeDictionnary (Dict* dict, OutStream* outStr, XRef *xRef, Guint numOffset, Guchar *fileKey,
-                               CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen, std::set<Dict*> *alreadyWrittenDicts)
-{
-  bool deleteSet = false;
-  if (!alreadyWrittenDicts) {
-    alreadyWrittenDicts = new std::set<Dict*>;
-    deleteSet = true;
-  }
-
-  if (alreadyWrittenDicts->find(dict) != alreadyWrittenDicts->end()) {
-    error(errSyntaxWarning, -1, "PDFDoc::writeDictionnary: Found recursive dicts");
-    if (deleteSet) delete alreadyWrittenDicts;
-    return;
-  } else {
-    alreadyWrittenDicts->insert(dict);
-  }
-
-  outStr->printf("<<");
-  for (int i=0; i<dict->getLength(); i++) {
-    GooString keyName(dict->getKey(i));
-    GooString *keyNameToPrint = keyName.sanitizedName(gFalse /* non ps mode */);
-    outStr->printf("/%s ", keyNameToPrint->getCString());
-    delete keyNameToPrint;
-    Object obj1 = dict->getValNF(i);
-    writeObject(&obj1, outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
-  }
-  outStr->printf(">> ");
-
-  if (deleteSet) {
-    delete alreadyWrittenDicts;
-  }
-}
-
-void PDFDoc::writeStream (Stream* str, OutStream* outStr)
-{
-  outStr->printf("stream\r\n");
-  str->reset();
-  for (int c=str->getChar(); c!= EOF; c=str->getChar()) {
-    outStr->printf("%c", c);  
-  }
-  outStr->printf("\r\nendstream\r\n");
-}
-
-void PDFDoc::writeRawStream (Stream* str, OutStream* outStr)
-{
-  Object obj1 = str->getDict()->lookup("Length");
-  if (!obj1.isInt() && !obj1.isInt64()) {
-    error (errSyntaxError, -1, "PDFDoc::writeRawStream, no Length in stream dict");
-    return;
-  }
-
-  Goffset length;
-  if (obj1.isInt())
-    length = obj1.getInt();
-  else
-    length = obj1.getInt64();
-
-  outStr->printf("stream\r\n");
-  str->unfilteredReset();
-  for (Goffset i = 0; i < length; i++) {
-    int c = str->getUnfilteredChar();
-    if (unlikely(c == EOF)) {
-      error (errSyntaxError, -1, "PDFDoc::writeRawStream: EOF reading stream");
-      break;
-    }
-    outStr->printf("%c", c);  
-  }
-  str->reset();
-  outStr->printf("\r\nendstream\r\n");
-}
-
-void PDFDoc::writeString (GooString* s, OutStream* outStr, Guchar *fileKey,
-                          CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen)
-{
-  // Encrypt string if encryption is enabled
-  GooString *sEnc = NULL;
-  if (fileKey) {
-    EncryptStream *enc = new EncryptStream(new MemStream(s->getCString(), 0, s->getLength(), Object(objNull)),
-                                           fileKey, encAlgorithm, keyLength, objNum, objGen);
-    sEnc = new GooString();
-    int c;
-    enc->reset();
-    while ((c = enc->getChar()) != EOF) {
-      sEnc->append((char)c);
-    }
-
-    delete enc;
-    s = sEnc;
-  }
-
-  // Write data
-  if (s->hasUnicodeMarker()) {
-    //unicode string don't necessary end with \0
-    const char* c = s->getCString();
-    outStr->printf("(");
-    for(int i=0; i<s->getLength(); i++) {
-      char unescaped = *(c+i)&0x000000ff;
-      //escape if needed
-      if (unescaped == '(' || unescaped == ')' || unescaped == '\\')
-        outStr->printf("%c", '\\');
-      outStr->printf("%c", unescaped);
-    }
-    outStr->printf(") ");
-  } else {
-    const char* c = s->getCString();
-    outStr->printf("(");
-    for(int i=0; i<s->getLength(); i++) {
-      char unescaped = *(c+i)&0x000000ff;
-      //escape if needed
-      if (unescaped == '\r')
-        outStr->printf("\\r");
-      else if (unescaped == '\n')
-        outStr->printf("\\n");
-      else {
-        if (unescaped == '(' || unescaped == ')' || unescaped == '\\') {
-          outStr->printf("%c", '\\');
-        }
-        outStr->printf("%c", unescaped);
-      }
-    }
-    outStr->printf(") ");
-  }
-
-  delete sEnc;
-}
-
-Goffset PDFDoc::writeObjectHeader (Ref *ref, OutStream* outStr)
-{
-  Goffset offset = outStr->getPos();
-  outStr->printf("%i %i obj ", ref->num, ref->gen);
-  return offset;
-}
-
-void PDFDoc::writeObject (Object* obj, OutStream* outStr, XRef *xRef, Guint numOffset, Guchar *fileKey,
-                          CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen, std::set<Dict*> *alreadyWrittenDicts)
-{
-  Array *array;
-
-  switch (obj->getType()) {
-    case objBool:
-      outStr->printf("%s ", obj->getBool()?"true":"false");
-      break;
-    case objInt:
-      outStr->printf("%i ", obj->getInt());
-      break;
-    case objInt64:
-      outStr->printf("%lli ", obj->getInt64());
-      break;
-    case objReal:
-    {
-      GooString s;
-      s.appendf("{0:.10g}", obj->getReal());
-      outStr->printf("%s ", s.getCString());
-      break;
-    }
-    case objString:
-      writeString(obj->getString(), outStr, fileKey, encAlgorithm, keyLength, objNum, objGen);
-      break;
-    case objName:
-    {
-      GooString name(obj->getName());
-      GooString *nameToPrint = name.sanitizedName(gFalse /* non ps mode */);
-      outStr->printf("/%s ", nameToPrint->getCString());
-      delete nameToPrint;
-      break;
-    }
-    case objNull:
-      outStr->printf( "null ");
-      break;
-    case objArray:
-      array = obj->getArray();
-      outStr->printf("[");
-      for (int i=0; i<array->getLength(); i++) {
-	Object obj1 = array->getNF(i);
-        writeObject(&obj1, outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen);
-      }
-      outStr->printf("] ");
-      break;
-    case objDict:
-      writeDictionnary (obj->getDict(), outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
-      break;
-    case objStream: 
-      {
-        //We can't modify stream with the current implementation (no write functions in Stream API)
-        // => the only type of streams which that have been modified are internal streams (=strWeird)
-        Stream *stream = obj->getStream();
-        if (stream->getKind() == strWeird || stream->getKind() == strCrypt) {
-          //we write the stream unencoded => TODO: write stream encoder
-
-          // Encrypt stream
-          EncryptStream *encStream = NULL;
-          GBool removeFilter = gTrue;
-          if (stream->getKind() == strWeird && fileKey) {
-            Object filter = stream->getDict()->lookup("Filter");
-            if (!filter.isName("Crypt")) {
-              if (filter.isArray()) {
-                for (int i = 0; i < filter.arrayGetLength(); i++) {
-                  Object filterEle = filter.arrayGet(i);
-                  if (filterEle.isName("Crypt")) {
-                    removeFilter = gFalse;
-                    break;
-                  }
-                }
-                if (removeFilter) {
-                  encStream = new EncryptStream(stream, fileKey, encAlgorithm, keyLength, objNum, objGen);
-                  encStream->setAutoDelete(gFalse);
-                  stream = encStream;
-                }
-              } else {
-                encStream = new EncryptStream(stream, fileKey, encAlgorithm, keyLength, objNum, objGen);
-                encStream->setAutoDelete(gFalse);
-                stream = encStream;
-              }
-            } else {
-              removeFilter = gFalse;
-            }
-          } else if (fileKey != NULL) { // Encrypt stream
-            encStream = new EncryptStream(stream, fileKey, encAlgorithm, keyLength, objNum, objGen);
-            encStream->setAutoDelete(gFalse);
-            stream = encStream;
-          }
-
-          stream->reset();
-          //recalculate stream length
-          Goffset tmp = 0;
-          for (int c=stream->getChar(); c!=EOF; c=stream->getChar()) {
-            tmp++;
-          }
-          stream->getDict()->set("Length", Object(tmp));
-
-          //Remove Stream encoding
-          if (removeFilter) {
-            stream->getDict()->remove("Filter");
-          }
-          stream->getDict()->remove("DecodeParms");
-
-          writeDictionnary (stream->getDict(),outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
-          writeStream (stream,outStr);
-          delete encStream;
-        } else {
-          //raw stream copy
-          FilterStream *fs = dynamic_cast<FilterStream*>(stream);
-          if (fs) {
-            BaseStream *bs = fs->getBaseStream();
-            if (bs) {
-              Goffset streamEnd;
-                if (xRef->getStreamEnd(bs->getStart(), &streamEnd)) {
-                  Goffset val = streamEnd - bs->getStart();
-                  stream->getDict()->set("Length", Object(val));
-                }
-              }
-          }
-          writeDictionnary (stream->getDict(), outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
-          writeRawStream (stream, outStr);
-        }
-        break;
-      }
-    case objRef:
-      outStr->printf("%i %i R ", obj->getRef().num + numOffset, obj->getRef().gen);
-      break;
-    case objCmd:
-      outStr->printf("%s\n", obj->getCmd());
-      break;
-    case objError:
-      outStr->printf("error\r\n");
-      break;
-    case objEOF:
-      outStr->printf("eof\r\n");
-      break;
-    case objNone:
-      outStr->printf("none\r\n");
-      break;
-    default:
-      error(errUnimplemented, -1,"Unhandled objType : {0:d}, please report a bug with a testcase\r\n", obj->getType());
-      break;
-  }
-}
-
-void PDFDoc::writeObjectFooter (OutStream* outStr)
-{
-  outStr->printf("endobj\r\n");
-}
-
-Object PDFDoc::createTrailerDict(int uxrefSize, GBool incrUpdate, Goffset startxRef,
-                                Ref *root, XRef *xRef, const char *fileName, Goffset fileSize)
-{
-  Dict *trailerDict = new Dict(xRef);
-  trailerDict->set("Size", Object(uxrefSize));
-
-  //build a new ID, as recommended in the reference, uses:
-  // - current time
-  // - file name
-  // - file size
-  // - values of entry in information dictionnary
-  GooString message;
-  char buffer[256];
-  sprintf(buffer, "%i", (int)time(NULL));
-  message.append(buffer);
-
-  if (fileName)
-    message.append(fileName);
-
-  sprintf(buffer, "%lli", (long long)fileSize);
-  message.append(buffer);
-
-  //info dict -- only use text string
-  if (!xRef->getTrailerDict()->isNone()) {
-    Object docInfo = xRef->getDocInfo();
-    if (docInfo.isDict()) {
-      for(int i=0; i<docInfo.getDict()->getLength(); i++) {
-        Object obj2 = docInfo.getDict()->getVal(i);
-        if (obj2.isString()) {
-          message.append(obj2.getString());
-        }
-      }
-    }
-  }
-
-  GBool hasEncrypt = gFalse;
-  if (!xRef->getTrailerDict()->isNone()) {
-    Object obj2 = xRef->getTrailerDict()->dictLookupNF("Encrypt");
-    if (!obj2.isNull()) {
-      trailerDict->set("Encrypt", std::move(obj2));
-      hasEncrypt = gTrue;
-    }
-  }
-
-  //calculate md5 digest
-  Guchar digest[16];
-  md5((Guchar*)message.getCString(), message.getLength(), digest);
-
-  //create ID array
-  // In case of encrypted files, the ID must not be changed because it's used to calculate the key
-  if (incrUpdate || hasEncrypt) {
-    //only update the second part of the array
-    Object obj4  = xRef->getTrailerDict()->getDict()->lookup("ID");
-    if (!obj4.isArray()) {
-      error(errSyntaxWarning, -1, "PDFDoc::createTrailerDict original file's ID entry isn't an array. Trying to continue");
-    } else {
-      Array *array = new Array(xRef);
-      //Get the first part of the ID
-      array->add(obj4.arrayGet(0));
-      array->add(Object(new GooString((const char*)digest, 16)));
-      trailerDict->set("ID", Object(array));
-    }
-  } else {
-    //new file => same values for the two identifiers
-    Array *array = new Array(xRef);
-    array->add(Object(new GooString((const char*)digest, 16)));
-    array->add(Object(new GooString((const char*)digest, 16)));
-    trailerDict->set("ID", Object(array));
-  }
-
-  trailerDict->set("Root", Object(root->num, root->gen));
-
-  if (incrUpdate) { 
-    trailerDict->set("Prev", Object(startxRef));
-  }
-  
-  if (!xRef->getTrailerDict()->isNone()) {
-    Object obj5 = xRef->getDocInfoNF();
-    if (!obj5.isNull()) {
-      trailerDict->set("Info", std::move(obj5));
-    }
-  }
-
-  return Object(trailerDict);
-}
-
-void PDFDoc::writeXRefTableTrailer(Object &&trailerDict, XRef *uxref, GBool writeAllEntries, Goffset uxrefOffset, OutStream* outStr, XRef *xRef)
-{
-  uxref->writeTableToFile( outStr, writeAllEntries );
-  outStr->printf( "trailer\r\n");
-  writeDictionnary(trailerDict.getDict(), outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0, nullptr);
-  outStr->printf( "\r\nstartxref\r\n");
-  outStr->printf( "%lli\r\n", uxrefOffset);
-  outStr->printf( "%%%%EOF\r\n");
-}
-
-void PDFDoc::writeXRefStreamTrailer (Object &&trailerDict, XRef *uxref, Ref *uxrefStreamRef, Goffset uxrefOffset, OutStream* outStr, XRef *xRef)
-{
-  GooString stmData;
-
-  // Fill stmData and some trailerDict fields
-  uxref->writeStreamToBuffer(&stmData, trailerDict.getDict(), xRef);
-
-  // Create XRef stream object and write it
-  MemStream *mStream = new MemStream( stmData.getCString(), 0, stmData.getLength(), std::move(trailerDict) );
-  writeObjectHeader(uxrefStreamRef, outStr);
-  Object obj1(static_cast<Stream*>(mStream));
-  writeObject(&obj1, outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0);
-  writeObjectFooter(outStr);
-
-  outStr->printf( "startxref\r\n");
-  outStr->printf( "%lli\r\n", uxrefOffset);
-  outStr->printf( "%%%%EOF\r\n");
-}
-
-void PDFDoc::writeXRefTableTrailer(Goffset uxrefOffset, XRef *uxref, GBool writeAllEntries,
-                                   int uxrefSize, OutStream* outStr, GBool incrUpdate)
-{
-  const char *fileNameA = fileName ? fileName->getCString() : NULL;
-  // file size (doesn't include the trailer)
-  unsigned int fileSize = 0;
-  int c;
-  str->reset();
-  while ((c = str->getChar()) != EOF) {
-    fileSize++;
-  }
-  str->close();
-  Ref ref;
-  ref.num = getXRef()->getRootNum();
-  ref.gen = getXRef()->getRootGen();
-  Object trailerDict = createTrailerDict(uxrefSize, incrUpdate, getStartXRef(), &ref,
-                                         getXRef(), fileNameA, fileSize);
-  writeXRefTableTrailer(std::move(trailerDict), uxref, writeAllEntries, uxrefOffset, outStr, getXRef());
-}
-
-void PDFDoc::writeHeader(OutStream *outStr, int major, int minor)
-{
-   outStr->printf("%%PDF-%d.%d\n", major, minor);
-   outStr->printf("%%\xE2\xE3\xCF\xD3\n");
-}
-
-void PDFDoc::markDictionnary (Dict* dict, XRef * xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts)
-{
-  bool deleteSet = false;
-  if (!alreadyMarkedDicts) {
-    alreadyMarkedDicts = new std::set<Dict*>;
-    deleteSet = true;
-  }
-
-  if (alreadyMarkedDicts->find(dict) != alreadyMarkedDicts->end()) {
-    error(errSyntaxWarning, -1, "PDFDoc::markDictionnary: Found recursive dicts");
-    if (deleteSet) delete alreadyMarkedDicts;
-    return;
-  } else {
-    alreadyMarkedDicts->insert(dict);
-  }
-
-  Object obj1;
-  for (int i=0; i<dict->getLength(); i++) {
-    const char *key = dict->getKey(i);
-    if (strcmp(key, "Annots") != 0) {
-      Object obj1 = dict->getValNF(i);
-      markObject(&obj1, xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
-    } else {
-      Object annotsObj = dict->getValNF(i);
-      if (!annotsObj.isNull()) {
-        markAnnotations(&annotsObj, xRef, countRef, 0, oldRefNum, newRefNum, alreadyMarkedDicts);
-      }
-    }
-  }
-
-  if (deleteSet) {
-    delete alreadyMarkedDicts;
-  }
-}
-
-void PDFDoc::markObject (Object* obj, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts)
-{
-  Array *array;
-
-  switch (obj->getType()) {
-    case objArray:
-      array = obj->getArray();
-      for (int i=0; i<array->getLength(); i++) {
-        Object obj1 = array->getNF(i);
-        markObject(&obj1, xRef, countRef, numOffset, oldRefNum, newRefNum);
-      }
-      break;
-    case objDict:
-      markDictionnary (obj->getDict(), xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
-      break;
-    case objStream: 
-      {
-        Stream *stream = obj->getStream();
-        markDictionnary (stream->getDict(), xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
-      }
-      break;
-    case objRef:
-      {
-        if (obj->getRef().num + (int) numOffset >= xRef->getNumObjects() || xRef->getEntry(obj->getRef().num + numOffset)->type == xrefEntryFree) {
-          if (getXRef()->getEntry(obj->getRef().num)->type == xrefEntryFree) {
-            return;  // already marked as free => should be replaced
-          }
-          xRef->add(obj->getRef().num + numOffset, obj->getRef().gen, 0, gTrue);
-          if (getXRef()->getEntry(obj->getRef().num)->type == xrefEntryCompressed) {
-            xRef->getEntry(obj->getRef().num + numOffset)->type = xrefEntryCompressed;
-          }
-        }
-        if (obj->getRef().num + (int) numOffset >= countRef->getNumObjects() || 
-            countRef->getEntry(obj->getRef().num + numOffset)->type == xrefEntryFree)
-        {
-          countRef->add(obj->getRef().num + numOffset, 1, 0, gTrue);
-        } else {
-          XRefEntry *entry = countRef->getEntry(obj->getRef().num + numOffset);
-          entry->gen++;
-          if (entry->gen > 9)
-            break;
-        } 
-        Object obj1 = getXRef()->fetch(obj->getRef().num, obj->getRef().gen);
-        markObject(&obj1, xRef, countRef, numOffset, oldRefNum, newRefNum);
-      }
-      break;
-    default:
-      break;
-  }
-}
-
-void PDFDoc::replacePageDict(int pageNo, int rotate,
-                             PDFRectangle *mediaBox, 
-                             PDFRectangle *cropBox)
-{
-  Ref *refPage = getCatalog()->getPageRef(pageNo);
-  Object page = getXRef()->fetch(refPage->num, refPage->gen);
-  Dict *pageDict = page.getDict();
-  pageDict->remove("MediaBoxssdf");
-  pageDict->remove("MediaBox");
-  pageDict->remove("CropBox");
-  pageDict->remove("ArtBox");
-  pageDict->remove("BleedBox");
-  pageDict->remove("TrimBox");
-  pageDict->remove("Rotate");
-  Array *mediaBoxArray = new Array(getXRef());
-  mediaBoxArray->add(Object(mediaBox->x1));
-  mediaBoxArray->add(Object(mediaBox->y1));
-  mediaBoxArray->add(Object(mediaBox->x2));
-  mediaBoxArray->add(Object(mediaBox->y2));
-  Object mediaBoxObject(mediaBoxArray);
-  Object trimBoxObject = mediaBoxObject.copy();
-  pageDict->add(copyString("MediaBox"), std::move(mediaBoxObject));
-  if (cropBox != NULL) {
-    Array *cropBoxArray = new Array(getXRef());
-    cropBoxArray->add(Object(cropBox->x1));
-    cropBoxArray->add(Object(cropBox->y1));
-    cropBoxArray->add(Object(cropBox->x2));
-    cropBoxArray->add(Object(cropBox->y2));
-    Object cropBoxObject(cropBoxArray);
-    trimBoxObject = cropBoxObject.copy();
-    pageDict->add(copyString("CropBox"), std::move(cropBoxObject));
-  }
-  pageDict->add(copyString("TrimBox"), std::move(trimBoxObject));
-  pageDict->add(copyString("Rotate"), Object(rotate));
-  getXRef()->setModifiedObject(&page, *refPage);
-}
-
-void PDFDoc::markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts)
-{
-  pageDict->remove("OpenAction");
-  pageDict->remove("Outlines");
-  pageDict->remove("StructTreeRoot");
-
-  for (int n = 0; n < pageDict->getLength(); n++) {
-    const char *key = pageDict->getKey(n);
-    Object value  = pageDict->getValNF(n);
-    if (strcmp(key, "Parent") != 0 &&
-	      strcmp(key, "Pages") != 0 &&
-	      strcmp(key, "AcroForm") != 0 &&
-	      strcmp(key, "Annots") != 0 &&
-	      strcmp(key, "P") != 0 &&
-        strcmp(key, "Root") != 0) {
-      markObject(&value, xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
-    }
-  }
-}
-
-GBool PDFDoc::markAnnotations(Object *annotsObj, XRef *xRef, XRef *countRef, Guint numOffset, int oldPageNum, int newPageNum, std::set<Dict*> *alreadyMarkedDicts) {
-  GBool modified = gFalse;
-  Object annots = annotsObj->fetch(getXRef());
-  if (annots.isArray()) {
-      Array *array = annots.getArray();
-      for (int i=array->getLength() - 1; i >= 0; i--) {
-        Object obj1 = array->get(i);
-        if (obj1.isDict()) {
-          Dict *dict = obj1.getDict();
-          Object type = dict->lookup("Type");
-          if (type.isName() && strcmp(type.getName(), "Annot") == 0) {
-            Object obj2 = dict->lookupNF("P");
-            if (obj2.isRef()) {
-              if (obj2.getRef().num == oldPageNum) {
-                Object obj3 = array->getNF(i);
-                if (obj3.isRef()) {
-                  dict->set("P", Object(newPageNum, 0));
-                  getXRef()->setModifiedObject(&obj1, obj3.getRef());
-                }
-              } else if (obj2.getRef().num == newPageNum) {
-                continue;
-              } else {
-                Object page  = getXRef()->fetch(obj2.getRef().num, obj2.getRef().gen);
-                if (page.isDict()) {
-                  Dict *dict = page.getDict();
-                  Object pagetype = dict->lookup("Type");
-                  if (!pagetype.isName() || strcmp(pagetype.getName(), "Page") != 0) {
-                    continue;
-                  }
-                }
-                array->remove(i);
-                modified = gTrue;
-                continue;
-              }
-            }
-          }
-          markPageObjects(dict, xRef, countRef, numOffset, oldPageNum, newPageNum, alreadyMarkedDicts);
-        }
-        obj1 = array->getNF(i);
-        if (obj1.isRef()) {
-          if (obj1.getRef().num + (int) numOffset >= xRef->getNumObjects() || xRef->getEntry(obj1.getRef().num + numOffset)->type == xrefEntryFree) {
-            if (getXRef()->getEntry(obj1.getRef().num)->type == xrefEntryFree) {
-              continue;  // already marked as free => should be replaced
-            }
-            xRef->add(obj1.getRef().num + numOffset, obj1.getRef().gen, 0, gTrue);
-            if (getXRef()->getEntry(obj1.getRef().num)->type == xrefEntryCompressed) {
-              xRef->getEntry(obj1.getRef().num + numOffset)->type = xrefEntryCompressed;
-            }
-          }
-          if (obj1.getRef().num + (int) numOffset >= countRef->getNumObjects() || 
-              countRef->getEntry(obj1.getRef().num + numOffset)->type == xrefEntryFree)
-          {
-            countRef->add(obj1.getRef().num + numOffset, 1, 0, gTrue);
-          } else {
-            XRefEntry *entry = countRef->getEntry(obj1.getRef().num + numOffset);
-            entry->gen++;
-          } 
-        }
-      }
-  }
-  if (annotsObj->isRef()) {
-    if (annotsObj->getRef().num + (int) numOffset >= xRef->getNumObjects() || xRef->getEntry(annotsObj->getRef().num + numOffset)->type == xrefEntryFree) {
-      if (getXRef()->getEntry(annotsObj->getRef().num)->type == xrefEntryFree) {
-        return modified;  // already marked as free => should be replaced
-      }
-      xRef->add(annotsObj->getRef().num + numOffset, annotsObj->getRef().gen, 0, gTrue);
-      if (getXRef()->getEntry(annotsObj->getRef().num)->type == xrefEntryCompressed) {
-        xRef->getEntry(annotsObj->getRef().num + numOffset)->type = xrefEntryCompressed;
-      }
-    }
-    if (annotsObj->getRef().num + (int) numOffset >= countRef->getNumObjects() || 
-        countRef->getEntry(annotsObj->getRef().num + numOffset)->type == xrefEntryFree)
-    {
-      countRef->add(annotsObj->getRef().num + numOffset, 1, 0, gTrue);
-    } else {
-      XRefEntry *entry = countRef->getEntry(annotsObj->getRef().num + numOffset);
-      entry->gen++;
-    } 
-    getXRef()->setModifiedObject(&annots, annotsObj->getRef());
-  }
-  return modified;
-}
-
-void PDFDoc::markAcroForm(Object *afObj, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum) {
-  GBool modified = gFalse;
-  Object acroform = afObj->fetch(getXRef());
-  if (acroform.isDict()) {
-      Dict *dict = acroform.getDict();
-      for (int i=0; i < dict->getLength(); i++) {
-        if (strcmp(dict->getKey(i), "Fields") == 0) {
-          Object fields = dict->getValNF(i);
-          modified = markAnnotations(&fields, xRef, countRef, numOffset, oldRefNum, newRefNum);
-        } else {
-          Object obj = dict->getValNF(i);
-          markObject(&obj, xRef, countRef, numOffset, oldRefNum, newRefNum);
-        }
-      }
-  }
-  if (afObj->isRef()) {
-    if (afObj->getRef().num + (int) numOffset >= xRef->getNumObjects() || xRef->getEntry(afObj->getRef().num + numOffset)->type == xrefEntryFree) {
-      if (getXRef()->getEntry(afObj->getRef().num)->type == xrefEntryFree) {
-        return;  // already marked as free => should be replaced
-      }
-      xRef->add(afObj->getRef().num + numOffset, afObj->getRef().gen, 0, gTrue);
-      if (getXRef()->getEntry(afObj->getRef().num)->type == xrefEntryCompressed) {
-        xRef->getEntry(afObj->getRef().num + numOffset)->type = xrefEntryCompressed;
-      }
-    }
-    if (afObj->getRef().num + (int) numOffset >= countRef->getNumObjects() || 
-        countRef->getEntry(afObj->getRef().num + numOffset)->type == xrefEntryFree)
-    {
-      countRef->add(afObj->getRef().num + numOffset, 1, 0, gTrue);
-    } else {
-      XRefEntry *entry = countRef->getEntry(afObj->getRef().num + numOffset);
-      entry->gen++;
-    } 
-    if (modified){
-      getXRef()->setModifiedObject(&acroform, afObj->getRef());
-    }
-  }
-  return;
-}
-
-Guint PDFDoc::writePageObjects(OutStream *outStr, XRef *xRef, Guint numOffset, GBool combine) 
-{
-  Guint objectsCount = 0; //count the number of objects in the XRef(s)
-  Guchar *fileKey;
-  CryptAlgorithm encAlgorithm;
-  int keyLength;
-  xRef->getEncryptionParameters(&fileKey, &encAlgorithm, &keyLength);
-
-  for (int n = numOffset; n < xRef->getNumObjects(); n++) {
-    if (xRef->getEntry(n)->type != xrefEntryFree) {
-      Ref ref;
-      ref.num = n;
-      ref.gen = xRef->getEntry(n)->gen;
-      objectsCount++;
-      Object obj = getXRef()->fetch(ref.num - numOffset, ref.gen);
-      Goffset offset = writeObjectHeader(&ref, outStr);
-      if (combine) {
-        writeObject(&obj, outStr, getXRef(), numOffset, NULL, cryptRC4, 0, 0, 0);
-      } else if (xRef->getEntry(n)->getFlag(XRefEntry::Unencrypted)) {
-        writeObject(&obj, outStr, NULL, cryptRC4, 0, 0, 0);
-      } else {
-        writeObject(&obj, outStr, fileKey, encAlgorithm, keyLength, ref.num, ref.gen);
-      }
-      writeObjectFooter(outStr);
-      xRef->add(ref.num, ref.gen, offset, gTrue);
-    }
-  }
-  return objectsCount;
-}
-
-#ifndef DISABLE_OUTLINE
-Outline *PDFDoc::getOutline()
-{
-  if (!outline) {
-    pdfdocLocker();
-    // read outline
-    outline = new Outline(catalog->getOutline(), xref);
-  }
-
-  return outline;
-}
-#endif
-
-PDFDoc *PDFDoc::ErrorPDFDoc(int errorCode, GooString *fileNameA)
-{
-  PDFDoc *doc = new PDFDoc();
-  doc->errCode = errorCode;
-  doc->fileName = fileNameA;
-
-  return doc;
-}
-
-long long PDFDoc::strToLongLong(char *s) {
-  long long x, d;
-  char *p;
-
-  x = 0;
-  for (p = s; *p && isdigit(*p & 0xff); ++p) {
-    d = *p - '0';
-    if (x > (LLONG_MAX - d) / 10) {
-      break;
-    }
-    x = 10 * x + d;
-  }
-  return x;
-}
-
-// Read the 'startxref' position.
-Goffset PDFDoc::getStartXRef(GBool tryingToReconstruct)
-{
-  if (startXRefPos == -1) {
-
-    if (isLinearized(tryingToReconstruct)) {
-      char buf[linearizationSearchSize+1];
-      int c, n, i;
-
-      str->setPos(0);
-      for (n = 0; n < linearizationSearchSize; ++n) {
-        if ((c = str->getChar()) == EOF) {
-          break;
-        }
-        buf[n] = c;
-      }
-      buf[n] = '\0';
-
-      // find end of first obj (linearization dictionary)
-      startXRefPos = 0;
-      for (i = 0; i < n; i++) {
-        if (!strncmp("endobj", &buf[i], 6)) {
-	  i += 6;
-	  //skip whitespace 
-	  while (buf[i] && Lexer::isSpace(buf[i])) ++i;
-	  startXRefPos = i;
-	  break;
-        }
-      }
-    } else {
-      char buf[xrefSearchSize+1];
-      char *p;
-      int c, n, i;
-
-      // read last xrefSearchSize bytes
-      int segnum = 0;
-      int maxXRefSearch = 24576;
-      if (str->getLength() < maxXRefSearch) maxXRefSearch = str->getLength();
-      for (; (xrefSearchSize - 16) * segnum < maxXRefSearch; segnum++) {
-        str->setPos((xrefSearchSize - 16) * segnum + xrefSearchSize, -1);
-        for (n = 0; n < xrefSearchSize; ++n) {
-          if ((c = str->getChar()) == EOF) {
-            break;
-          }
-          buf[n] = c;
-        }
-        buf[n] = '\0';
-
-        // find startxref
-        for (i = n - 9; i >= 0; --i) {
-          if (!strncmp(&buf[i], "startxref", 9)) {
-            break;
-          }
-        }
-        if (i < 0) {
-          startXRefPos = 0;
-        } else {
-          for (p = &buf[i + 9]; isspace(*p); ++p);
-          startXRefPos = strToLongLong(p);
-          break;
-        }
-      }
-    }
-
-  }
-
-  return startXRefPos;
-}
-
-Goffset PDFDoc::getMainXRefEntriesOffset(GBool tryingToReconstruct)
-{
-  Guint mainXRefEntriesOffset = 0;
-
-  if (isLinearized(tryingToReconstruct)) {
-    mainXRefEntriesOffset = getLinearization()->getMainXRefEntriesOffset();
-  }
-
-  return mainXRefEntriesOffset;
-}
-
-int PDFDoc::getNumPages()
-{
-  if (isLinearized()) {
-    int n;
-    if ((n = getLinearization()->getNumPages())) {
-      return n;
-    }
-  }
-
-  return catalog->getNumPages();
-}
-
-Page *PDFDoc::parsePage(int page)
-{
-  Ref pageRef;
-
-  pageRef.num = getHints()->getPageObjectNum(page);
-  if (!pageRef.num) {
-    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(errSyntaxWarning, -1, "Invalid object num ({0:d}) for page {1:d}", pageRef.num, page);
-    return NULL;
-  }
-
-  pageRef.gen = xref->getEntry(pageRef.num)->gen;
-  Object obj = xref->fetch(pageRef.num, pageRef.gen);
-  if (!obj.isDict("Page")) {
-    error(errSyntaxWarning, -1, "Object ({0:d} {1:d}) is not a pageDict", pageRef.num, pageRef.gen);
-    return NULL;
-  }
-  Dict *pageDict = obj.getDict();
-
-  return new Page(this, page, &obj, pageRef,
-               new PageAttrs(NULL, pageDict), catalog->getForm());
-}
-
-Page *PDFDoc::getPage(int page)
-{
-  if ((page < 1) || page > getNumPages()) return NULL;
-
-  if (isLinearized() && checkLinearization()) {
-    pdfdocLocker();
-    if (!pageCache) {
-      pageCache = (Page **) gmallocn(getNumPages(), sizeof(Page *));
-      for (int i = 0; i < getNumPages(); i++) {
-        pageCache[i] = NULL;
-      }
-    }
-    if (!pageCache[page-1]) {
-      pageCache[page-1] = parsePage(page);
-    }
-    if (pageCache[page-1]) {
-       return pageCache[page-1];
-    } else {
-       error(errSyntaxWarning, -1, "Failed parsing page {0:d} using hint tables", page);
-    }
-  }
-
-  return catalog->getPage(page);
-}
diff --git a/source/libs/poppler/poppler-src/poppler/PDFDoc.cc~ b/source/libs/poppler/poppler-src/poppler/PDFDoc.cc~
deleted file mode 100644
index 90f039d8e..000000000
--- a/source/libs/poppler/poppler-src/poppler/PDFDoc.cc~
+++ /dev/null
@@ -1,1985 +0,0 @@
-//========================================================================
-//
-// PDFDoc.cc
-//
-// Copyright 1996-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-//========================================================================
-//
-// Modified under the Poppler project - http://poppler.freedesktop.org
-//
-// All changes made under the Poppler project to this file are licensed
-// under GPL version 2 or later
-//
-// Copyright (C) 2005, 2006, 2008 Brad Hards <bradh@frogmouth.net>
-// Copyright (C) 2005, 2007-2009, 2011-2017 Albert Astals Cid <aacid@kde.org>
-// Copyright (C) 2008 Julien Rebetez <julienr@svn.gnome.org>
-// Copyright (C) 2008, 2010 Pino Toscano <pino@kde.org>
-// Copyright (C) 2008, 2010, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
-// Copyright (C) 2009 Eric Toombs <ewtoombs@uwaterloo.ca>
-// Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
-// Copyright (C) 2009, 2011 Axel Struebing <axel.struebing@freenet.de>
-// Copyright (C) 2010-2012, 2014 Hib Eris <hib@hiberis.nl>
-// Copyright (C) 2010 Jakub Wilk <jwilk@jwilk.net>
-// Copyright (C) 2010 Ilya Gorenbein <igorenbein@finjan.com>
-// Copyright (C) 2010 Srinivas Adicherla <srinivas.adicherla@geodesic.com>
-// Copyright (C) 2010 Philip Lorenz <lorenzph+freedesktop@gmail.com>
-// Copyright (C) 2011-2016 Thomas Freitag <Thomas.Freitag@alfa.de>
-// Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
-// Copyright (C) 2013, 2014, 2017 Adrian Johnson <ajohnson@redneon.com>
-// Copyright (C) 2013 Adam Reichold <adamreichold@myopera.com>
-// Copyright (C) 2014 Bogdan Cristea <cristeab@gmail.com>
-// Copyright (C) 2015 Li Junling <lijunling@sina.com>
-// Copyright (C) 2015 André Guerreiro <aguerreiro1985@gmail.com>
-// Copyright (C) 2015 André Esser <bepandre@hotmail.com>
-// Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
-// Copyright (C) 2017 Jean Ghali <jghali@libertysurf.fr>
-//
-// To see a description of the changes please see the Changelog file that
-// came with your tarball or type make ChangeLog if you are building from git
-//
-//========================================================================
-
-#include <config.h>
-#include <poppler-config.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include <ctype.h>
-#include <locale.h>
-#include <stdio.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <time.h>
-#include <sys/stat.h>
-#include "goo/glibc.h"
-#include "goo/gstrtod.h"
-#include "goo/GooString.h"
-#include "goo/gfile.h"
-#include "poppler-config.h"
-#include "GlobalParams.h"
-#include "Page.h"
-#include "Catalog.h"
-#include "Stream.h"
-#include "XRef.h"
-#include "Linearization.h"
-#include "Link.h"
-#include "OutputDev.h"
-#include "Error.h"
-#include "ErrorCodes.h"
-#include "Lexer.h"
-#include "Parser.h"
-#include "SecurityHandler.h"
-#include "Decrypt.h"
-#ifndef DISABLE_OUTLINE
-#include "Outline.h"
-#endif
-#include "PDFDoc.h"
-#include "Hints.h"
-#include "UTF.h"
-
-#ifdef MULTITHREADED
-#  define pdfdocLocker()   MutexLocker locker(&mutex)
-#else
-#  define pdfdocLocker()
-#endif
-
-//------------------------------------------------------------------------
-
-#define headerSearchSize 1024	// read this many bytes at beginning of
-				//   file to look for '%PDF'
-#define pdfIdLength 32   // PDF Document IDs (PermanentId, UpdateId) length
-
-#define linearizationSearchSize 1024	// read this many bytes at beginning of
-					// file to look for linearization
-					// dictionary
-
-#define xrefSearchSize 1024	// read this many bytes at end of file
-				//   to look for 'startxref'
-
-//------------------------------------------------------------------------
-// PDFDoc
-//------------------------------------------------------------------------
-
-void PDFDoc::init()
-{
-#ifdef MULTITHREADED
-  gInitMutex(&mutex);
-#endif
-  ok = gFalse;
-  errCode = errNone;
-  fileName = NULL;
-  file = NULL;
-  str = NULL;
-  xref = NULL;
-  linearization = NULL;
-  catalog = NULL;
-  hints = NULL;
-#ifndef DISABLE_OUTLINE
-  outline = NULL;
-#endif
-  startXRefPos = -1;
-  secHdlr = NULL;
-  pageCache = NULL;
-}
-
-PDFDoc::PDFDoc()
-{
-  init();
-}
-
-PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword,
-	       GooString *userPassword, void *guiDataA) {
-#ifdef _WIN32
-  int n, i;
-#endif
-
-  init();
-
-  fileName = fileNameA;
-  guiData = guiDataA;
-#ifdef _WIN32
-  n = fileName->getLength();
-  fileNameU = (wchar_t *)gmallocn(n + 1, sizeof(wchar_t));
-  for (i = 0; i < n; ++i) {
-    fileNameU[i] = (wchar_t)(fileName->getChar(i) & 0xff);
-  }
-  fileNameU[n] = L'\0';
-#endif
-
-  // try to open file
-#ifdef _WIN32
-  wchar_t *wFileName = (wchar_t*)utf8ToUtf16(fileName->getCString());
-  file = GooFile::open(wFileName);
-  gfree(wFileName);
-#else
-   file = GooFile::open(fileName);
-#endif
-  if (file == NULL) {
-    // fopen() has failed.
-    // Keep a copy of the errno returned by fopen so that it can be 
-    // referred to later.
-    fopenErrno = errno;
-    error(errIO, -1, "Couldn't open file '{0:t}': {1:s}.", fileName, strerror(errno));
-    errCode = errOpenFile;
-    return;
-  }
-
-  // create stream
-  str = new FileStream(file, 0, gFalse, file->size(), Object(objNull));
-
-  ok = setup(ownerPassword, userPassword);
-}
-
-#ifdef _WIN32
-PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword,
-	       GooString *userPassword, void *guiDataA) {
-  OSVERSIONINFO version;
-  int i;
-
-  init();
-
-  guiData = guiDataA;
-
-  // save both Unicode and 8-bit copies of the file name
-  fileName = new GooString();
-  fileNameU = (wchar_t *)gmallocn(fileNameLen + 1, sizeof(wchar_t));
-  for (i = 0; i < fileNameLen; ++i) {
-    fileName->append((char)fileNameA[i]);
-    fileNameU[i] = fileNameA[i];
-  }
-  fileNameU[fileNameLen] = L'\0';
-  
-  // try to open file
-  // NB: _wfopen is only available in NT
-  version.dwOSVersionInfoSize = sizeof(version);
-  GetVersionEx(&version);
-  if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-    file = GooFile::open(fileNameU);
-  } else {
-    file = GooFile::open(fileName);
-  }
-  if (!file) {
-    error(errIO, -1, "Couldn't open file '{0:t}'", fileName);
-    errCode = errOpenFile;
-    return;
-  }
-
-  // create stream
-  str = new FileStream(file, 0, gFalse, file->size(), Object(objNull));
-
-  ok = setup(ownerPassword, userPassword);
-}
-#endif
-
-PDFDoc::PDFDoc(BaseStream *strA, GooString *ownerPassword,
-	       GooString *userPassword, void *guiDataA) {
-#ifdef _WIN32
-  int n, i;
-#endif
-
-  init();
-  guiData = guiDataA;
-  if (strA->getFileName()) {
-    fileName = strA->getFileName()->copy();
-#ifdef _WIN32
-    n = fileName->getLength();
-    fileNameU = (wchar_t *)gmallocn(n + 1, sizeof(wchar_t));
-    for (i = 0; i < n; ++i) {
-      fileNameU[i] = (wchar_t)(fileName->getChar(i) & 0xff);
-    }
-    fileNameU[n] = L'\0';
-#endif
-  } else {
-    fileName = NULL;
-#ifdef _WIN32
-    fileNameU = NULL;
-#endif
-  }
-  str = strA;
-  ok = setup(ownerPassword, userPassword);
-}
-
-GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) {
-  pdfdocLocker();
-  str->setPos(0, -1);
-  if (str->getPos() < 0)
-  {
-    error(errSyntaxError, -1, "Document base stream is not seekable");
-    return gFalse;
-  }
-
-  str->reset();
-
-  // check footer
-  // Adobe does not seem to enforce %%EOF, so we do the same
-//  if (!checkFooter()) return gFalse;
-  
-  // check header
-  checkHeader();
-
-  GBool wasReconstructed = false;
-
-  // read xref table
-  xref = new XRef(str, getStartXRef(), getMainXRefEntriesOffset(), &wasReconstructed);
-  if (!xref->isOk()) {
-    if (wasReconstructed) {
-      delete xref;
-      startXRefPos = -1;
-      xref = new XRef(str, getStartXRef(gTrue), getMainXRefEntriesOffset(gTrue), &wasReconstructed);
-    }
-    if (!xref->isOk()) {
-      error(errSyntaxError, -1, "Couldn't read xref table");
-      errCode = xref->getErrorCode();
-      return gFalse;
-    }
-  }
-
-  // check for encryption
-  if (!checkEncryption(ownerPassword, userPassword)) {
-    errCode = errEncrypted;
-    return gFalse;
-  }
-
-  // read catalog
-  catalog = new Catalog(this);
-  if (catalog && !catalog->isOk()) {
-    if (!wasReconstructed)
-    {
-      // try one more time to contruct the Catalog, maybe the problem is damaged XRef 
-      delete catalog;
-      delete xref;
-      xref = new XRef(str, 0, 0, NULL, true);
-      catalog = new Catalog(this);
-    }
-
-    if (catalog && !catalog->isOk()) {
-      error(errSyntaxError, -1, "Couldn't read page catalog");
-      errCode = errBadCatalog;
-      return gFalse;
-    }
-  }
-
-  // done
-  return gTrue;
-}
-
-PDFDoc::~PDFDoc() {
-  if (pageCache) {
-    for (int i = 0; i < getNumPages(); i++) {
-      if (pageCache[i]) {
-        delete pageCache[i];
-      }
-    }
-    gfree(pageCache);
-  }
-  delete secHdlr;
-#ifndef DISABLE_OUTLINE
-  if (outline) {
-    delete outline;
-  }
-#endif
-  if (catalog) {
-    delete catalog;
-  }
-  if (xref) {
-    delete xref;
-  }
-  if (hints) {
-    delete hints;
-  }
-  if (linearization) {
-    delete linearization;
-  }
-  if (str) {
-    delete str;
-  }
-  if (file) {
-    delete file;
-  }
-  if (fileName) {
-    delete fileName;
-  }
-#ifdef _WIN32
-  if (fileNameU) {
-    gfree(fileNameU);
-  }
-#endif
-#ifdef MULTITHREADED
-  gDestroyMutex(&mutex);
-#endif
-}
-
-
-// Check for a %%EOF at the end of this stream
-GBool PDFDoc::checkFooter() {
-  // we look in the last 1024 chars because Adobe does the same
-  char *eof = new char[1025];
-  Goffset pos = str->getPos();
-  str->setPos(1024, -1);
-  int i, ch;
-  for (i = 0; i < 1024; i++)
-  {
-    ch = str->getChar();
-    if (ch == EOF)
-      break;
-    eof[i] = ch;
-  }
-  eof[i] = '\0';
-
-  bool found = false;
-  for (i = i - 5; i >= 0; i--) {
-    if (strncmp (&eof[i], "%%EOF", 5) == 0) {
-      found = true;
-      break;
-    }
-  }
-  if (!found)
-  {
-    error(errSyntaxError, -1, "Document has not the mandatory ending %%EOF");
-    errCode = errDamaged;
-    delete[] eof;
-    return gFalse;
-  }
-  delete[] eof;
-  str->setPos(pos);
-  return gTrue;
-}
-  
-// Check for a PDF header on this stream.  Skip past some garbage
-// if necessary.
-void PDFDoc::checkHeader() {
-  char hdrBuf[headerSearchSize+1];
-  char *p;
-  char *tokptr;
-  int i;
-
-  pdfMajorVersion = 0;
-  pdfMinorVersion = 0;
-  for (i = 0; i < headerSearchSize; ++i) {
-    hdrBuf[i] = str->getChar();
-  }
-  hdrBuf[headerSearchSize] = '\0';
-  for (i = 0; i < headerSearchSize - 5; ++i) {
-    if (!strncmp(&hdrBuf[i], "%PDF-", 5)) {
-      break;
-    }
-  }
-  if (i >= headerSearchSize - 5) {
-    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(errSyntaxWarning, -1, "May not be a PDF file (continuing anyway)");
-    return;
-  }
-  sscanf(p, "%d.%d", &pdfMajorVersion, &pdfMinorVersion);
-  // We don't do the version check. Don't add it back in.
-}
-
-GBool PDFDoc::checkEncryption(GooString *ownerPassword, GooString *userPassword) {
-  GBool encrypted;
-  GBool ret;
-
-  Object encrypt = xref->getTrailerDict()->dictLookup("Encrypt");
-  if ((encrypted = encrypt.isDict())) {
-    if ((secHdlr = SecurityHandler::make(this, &encrypt))) {
-      if (secHdlr->isUnencrypted()) {
-	// no encryption
-	ret = gTrue;
-      } else if (secHdlr->checkEncryption(ownerPassword, userPassword)) {
-	// authorization succeeded
-       	xref->setEncryption(secHdlr->getPermissionFlags(),
-			    secHdlr->getOwnerPasswordOk(),
-			    secHdlr->getFileKey(),
-			    secHdlr->getFileKeyLength(),
-			    secHdlr->getEncVersion(),
-			    secHdlr->getEncRevision(),
-			    secHdlr->getEncAlgorithm());
-	ret = gTrue;
-      } else {
-	// authorization failed
-	ret = gFalse;
-      }
-    } else {
-      // couldn't find the matching security handler
-      ret = gFalse;
-    }
-  } else {
-    // document is not encrypted
-    ret = gTrue;
-  }
-  return ret;
-}
-
-std::vector<FormWidgetSignature*> PDFDoc::getSignatureWidgets()
-{
-  int num_pages = getNumPages();
-  FormPageWidgets *page_widgets = NULL;
-  std::vector<FormWidgetSignature*> widget_vector;
-
-  for (int i = 1; i <= num_pages; i++) {
-    Page *p = getCatalog()->getPage(i);
-    if (p) {
-      page_widgets = p->getFormWidgets();
-      for (int j = 0; page_widgets != NULL && j < page_widgets->getNumWidgets(); j++) {
-	if (page_widgets->getWidget(j)->getType() == formSignature) {
-	    widget_vector.push_back(static_cast<FormWidgetSignature*>(page_widgets->getWidget(j)));
-	}
-      }
-      delete page_widgets;
-    }
-  }
-  return widget_vector;
-}
-
-void PDFDoc::displayPage(OutputDev *out, int page,
-			 double hDPI, double vDPI, int rotate,
-			 GBool useMediaBox, GBool crop, GBool printing,
-			 GBool (*abortCheckCbk)(void *data),
-			 void *abortCheckCbkData,
-                         GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
-                         void *annotDisplayDecideCbkData, GBool copyXRef) {
-  if (globalParams->getPrintCommands()) {
-    printf("***** page %d *****\n", page);
-  }
-
-  if (getPage(page))
-    getPage(page)->display(out, hDPI, vDPI,
-				    rotate, useMediaBox, crop, printing,
-				    abortCheckCbk, abortCheckCbkData,
-				    annotDisplayDecideCbk, annotDisplayDecideCbkData, copyXRef);
-
-}
-
-void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage,
-			  double hDPI, double vDPI, int rotate,
-			  GBool useMediaBox, GBool crop, GBool printing,
-			  GBool (*abortCheckCbk)(void *data),
-			  void *abortCheckCbkData,
-                          GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
-                          void *annotDisplayDecideCbkData) {
-  int page;
-
-  for (page = firstPage; page <= lastPage; ++page) {
-    displayPage(out, page, hDPI, vDPI, rotate, useMediaBox, crop, printing,
-		abortCheckCbk, abortCheckCbkData,
-                annotDisplayDecideCbk, annotDisplayDecideCbkData);
-  }
-}
-
-void PDFDoc::displayPageSlice(OutputDev *out, int page,
-			      double hDPI, double vDPI, int rotate,
-			      GBool useMediaBox, GBool crop, GBool printing,
-			      int sliceX, int sliceY, int sliceW, int sliceH,
-			      GBool (*abortCheckCbk)(void *data),
-			      void *abortCheckCbkData,
-                              GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
-                              void *annotDisplayDecideCbkData, GBool copyXRef) {
-  if (getPage(page))
-    getPage(page)->displaySlice(out, hDPI, vDPI,
-					 rotate, useMediaBox, crop,
-					 sliceX, sliceY, sliceW, sliceH,
-					 printing,
-					 abortCheckCbk, abortCheckCbkData,
-					 annotDisplayDecideCbk, annotDisplayDecideCbkData, copyXRef);
-}
-
-Links *PDFDoc::getLinks(int page) {
-  Page *p = getPage(page);
-  if (!p) {
-    return new Links (NULL);
-  }
-  return p->getLinks();
-}
-
-void PDFDoc::processLinks(OutputDev *out, int page) {
-  if (getPage(page))
-    getPage(page)->processLinks(out);
-}
-
-Linearization *PDFDoc::getLinearization()
-{
-  if (!linearization) {
-    linearization = new Linearization(str);
-    linearizationState = 0;
-  }
-  return linearization;
-}
-
-GBool PDFDoc::checkLinearization() {
-  if (linearization == NULL)
-    return gFalse;
-  if (linearizationState == 1)
-    return gTrue;
-  if (linearizationState == 2)
-    return gFalse;
-  if (!hints) {
-    hints = new Hints(str, linearization, getXRef(), secHdlr);
-  }
-  if (!hints->isOk()) {
-    linearizationState = 2;
-    return gFalse;
-  }
-  for (int page = 1; page <= linearization->getNumPages(); page++) {
-    Ref pageRef;
-
-    pageRef.num = hints->getPageObjectNum(page);
-    if (!pageRef.num) {
-      linearizationState = 2;
-      return gFalse;
-    }
-
-    // check for bogus ref - this can happen in corrupted PDF files
-    if (pageRef.num < 0 || pageRef.num >= xref->getNumObjects()) {
-      linearizationState = 2;
-      return gFalse;
-    }
-
-    pageRef.gen = xref->getEntry(pageRef.num)->gen;
-    Object obj = xref->fetch(pageRef.num, pageRef.gen);
-    if (!obj.isDict("Page")) {
-      linearizationState = 2;
-      return gFalse;
-    }
-  }
-  linearizationState = 1;
-  return gTrue;
-}
-
-GBool PDFDoc::isLinearized(GBool tryingToReconstruct) {
-  if ((str->getLength()) &&
-      (getLinearization()->getLength() == str->getLength()))
-    return gTrue;
-  else {
-    if (tryingToReconstruct)
-      return getLinearization()->getLength() > 0;
-    else
-      return gFalse;
-  }
-}
-
-void PDFDoc::setDocInfoModified(Object *infoObj)
-{
-  Object infoObjRef = getDocInfoNF();
-  xref->setModifiedObject(infoObj, infoObjRef.getRef());
-}
-
-void PDFDoc::setDocInfoStringEntry(const char *key, GooString *value)
-{
-  GBool removeEntry = !value || value->getLength() == 0 || value->hasJustUnicodeMarker();
-  if (removeEntry) {
-    delete value;
-  }
-
-  Object infoObj = getDocInfo();
-  if (infoObj.isNull() && removeEntry) {
-    // No info dictionary, so no entry to remove.
-    return;
-  }
-
-  infoObj = createDocInfoIfNoneExists();
-  if (removeEntry) {
-    infoObj.dictSet(key, Object(objNull));
-  } else {
-    infoObj.dictSet(key, Object(value));
-  }
-
-
-  if (infoObj.dictGetLength() == 0) {
-    // Info dictionary is empty. Remove it altogether.
-    removeDocInfo();
-  } else {
-    setDocInfoModified(&infoObj);
-  }
-}
-
-GooString *PDFDoc::getDocInfoStringEntry(const char *key) {
-  Object infoObj = getDocInfo();
-  if (!infoObj.isDict()) {
-      return NULL;
-  }
-
-  Object entryObj = infoObj.dictLookup(key);
-
-  GooString *result;
-
-  if (entryObj.isString()) {
-    result = entryObj.takeString();
-  } else {
-    result = NULL;
-  }
-
-  return result;
-}
-
-static GBool
-get_id (GooString *encodedidstring, GooString *id) {
-  const char *encodedid = encodedidstring->getCString();
-  char pdfid[pdfIdLength + 1];
-  int n;
-
-  if (encodedidstring->getLength() != pdfIdLength / 2)
-    return gFalse;
-
-  n = sprintf(pdfid, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
-	      encodedid[0] & 0xff, encodedid[1] & 0xff, encodedid[2] & 0xff, encodedid[3] & 0xff,
-	      encodedid[4] & 0xff, encodedid[5] & 0xff, encodedid[6] & 0xff, encodedid[7] & 0xff,
-	      encodedid[8] & 0xff, encodedid[9] & 0xff, encodedid[10] & 0xff, encodedid[11] & 0xff,
-	      encodedid[12] & 0xff, encodedid[13] & 0xff, encodedid[14] & 0xff, encodedid[15] & 0xff);
-  if (n != pdfIdLength)
-    return gFalse;
-
-  id->Set(pdfid, pdfIdLength);
-  return gTrue;
-}
-
-GBool PDFDoc::getID(GooString *permanent_id, GooString *update_id) {
-  Object obj = xref->getTrailerDict()->dictLookup ("ID");
-
-  if (obj.isArray() && obj.arrayGetLength() == 2) {
-    if (permanent_id) {
-      Object obj2 = obj.arrayGet(0);
-      if (obj2.isString()) {
-        if (!get_id (obj2.getString(), permanent_id)) {
-	  return gFalse;
-	}
-      } else {
-        error(errSyntaxError, -1, "Invalid permanent ID");
-	return gFalse;
-      }
-    }
-
-    if (update_id) {
-      Object obj2 = obj.arrayGet(1);
-      if (obj2.isString()) {
-        if (!get_id (obj2.getString(), update_id)) {
-	  return gFalse;
-	}
-      } else {
-        error(errSyntaxError, -1, "Invalid update ID");
-	return gFalse;
-      }
-    }
-
-    return gTrue;
-  }
-
-  return gFalse;
-}
-
-Hints *PDFDoc::getHints()
-{
-  if (!hints && isLinearized()) {
-    hints = new Hints(str, getLinearization(), getXRef(), secHdlr);
-  }
-
-  return hints;
-}
-
-int PDFDoc::savePageAs(GooString *name, int pageNo) 
-{
-  FILE *f;
-  OutStream *outStr;
-  XRef *yRef, *countRef;
-  int rootNum = getXRef()->getNumObjects() + 1;
-
-  // Make sure that special flags are set, because we are going to read
-  // all objects, including Unencrypted ones.
-  xref->scanSpecialFlags();
-
-  Guchar *fileKey;
-  CryptAlgorithm encAlgorithm;
-  int keyLength;
-  xref->getEncryptionParameters(&fileKey, &encAlgorithm, &keyLength);
-
-  if (pageNo < 1 || pageNo > getNumPages() || !getCatalog()->getPage(pageNo)) {
-    error(errInternal, -1, "Illegal pageNo: {0:d}({1:d})", pageNo, getNumPages() );
-    return errOpenFile;
-  }
-  PDFRectangle *cropBox = NULL;
-  if (getCatalog()->getPage(pageNo)->isCropped()) {
-    cropBox = getCatalog()->getPage(pageNo)->getCropBox();
-  }
-  replacePageDict(pageNo, 
-    getCatalog()->getPage(pageNo)->getRotate(),
-    getCatalog()->getPage(pageNo)->getMediaBox(),
-    cropBox);
-  Ref *refPage = getCatalog()->getPageRef(pageNo);
-  Object page = getXRef()->fetch(refPage->num, refPage->gen);
-
-  if (!(f = fopen(name->getCString(), "wb"))) {
-    error(errIO, -1, "Couldn't open file '{0:t}'", name);
-    return errOpenFile;
-  }
-  outStr = new FileOutStream(f,0);
-
-  yRef = new XRef(getXRef()->getTrailerDict());
-
-  if (secHdlr != NULL && !secHdlr->isUnencrypted()) {
-    yRef->setEncryption(secHdlr->getPermissionFlags(), 
-      secHdlr->getOwnerPasswordOk(), fileKey, keyLength, secHdlr->getEncVersion(), secHdlr->getEncRevision(), encAlgorithm);
-  }
-  countRef = new XRef();
-  Object *trailerObj = getXRef()->getTrailerDict();
-  if (trailerObj->isDict()) {
-    markPageObjects(trailerObj->getDict(), yRef, countRef, 0, refPage->num, rootNum + 2);
-  }
-  yRef->add(0, 65535, 0, gFalse);
-  writeHeader(outStr, getPDFMajorVersion(), getPDFMinorVersion());
-
-  // get and mark info dict
-  Object infoObj = getXRef()->getDocInfo();
-  if (infoObj.isDict()) {
-    Dict *infoDict = infoObj.getDict();
-    markPageObjects(infoDict, yRef, countRef, 0, refPage->num, rootNum + 2);
-    if (trailerObj->isDict()) {
-      Dict *trailerDict = trailerObj->getDict();
-      Object ref = trailerDict->lookupNF("Info");
-      if (ref.isRef()) {
-        yRef->add(ref.getRef().num, ref.getRef().gen, 0, gTrue);
-        if (getXRef()->getEntry(ref.getRef().num)->type == xrefEntryCompressed) {
-          yRef->getEntry(ref.getRef().num)->type = xrefEntryCompressed;
-        }
-      }
-    }
-  }
-  
-  // get and mark output intents etc.
-  Object catObj = getXRef()->getCatalog();
-  Dict *catDict = catObj.getDict();
-  Object pagesObj = catDict->lookup("Pages");
-  Object afObj = catDict->lookupNF("AcroForm");
-  if (!afObj.isNull()) {
-    markAcroForm(&afObj, yRef, countRef, 0, refPage->num, rootNum + 2);
-  }
-  Dict *pagesDict = pagesObj.getDict();
-  Object resourcesObj = pagesDict->lookup("Resources");
-  if (resourcesObj.isDict())
-    markPageObjects(resourcesObj.getDict(), yRef, countRef, 0, refPage->num, rootNum + 2);
-  markPageObjects(catDict, yRef, countRef, 0, refPage->num, rootNum + 2);
-
-  Dict *pageDict = page.getDict();
-  if (resourcesObj.isNull() && !pageDict->hasKey("Resources")) {
-    Object *resourceDictObject = getCatalog()->getPage(pageNo)->getResourceDictObject();
-    if (resourceDictObject->isDict()) {
-      resourcesObj = resourceDictObject->copy();
-      markPageObjects(resourcesObj.getDict(), yRef, countRef, 0, refPage->num, rootNum + 2);
-    }
-  }
-  markPageObjects(pageDict, yRef, countRef, 0, refPage->num, rootNum + 2);
-  Object annotsObj = pageDict->lookupNF("Annots");
-  if (!annotsObj.isNull()) {
-    markAnnotations(&annotsObj, yRef, countRef, 0, refPage->num, rootNum + 2);
-  }
-  yRef->markUnencrypted();
-  writePageObjects(outStr, yRef, 0);
-
-  yRef->add(rootNum,0,outStr->getPos(),gTrue);
-  outStr->printf("%d 0 obj\n", rootNum);
-  outStr->printf("<< /Type /Catalog /Pages %d 0 R", rootNum + 1); 
-  for (int j = 0; j < catDict->getLength(); j++) {
-    const char *key = catDict->getKey(j);
-    if (strcmp(key, "Type") != 0 &&
-      strcmp(key, "Catalog") != 0 &&
-      strcmp(key, "Pages") != 0) 
-    {
-      if (j > 0) outStr->printf(" ");
-      Object value = catDict->getValNF(j);
-      outStr->printf("/%s ", key);
-      writeObject(&value, outStr, getXRef(), 0, NULL, cryptRC4, 0, 0, 0);
-    }
-  }
-  outStr->printf(">>\nendobj\n");
-
-  yRef->add(rootNum + 1,0,outStr->getPos(),gTrue);
-  outStr->printf("%d 0 obj\n", rootNum + 1);
-  outStr->printf("<< /Type /Pages /Kids [ %d 0 R ] /Count 1 ", rootNum + 2);
-  if (resourcesObj.isDict()) {
-    outStr->printf("/Resources ");
-    writeObject(&resourcesObj, outStr, getXRef(), 0, NULL, cryptRC4, 0, 0, 0);
-  }
-  outStr->printf(">>\n");
-  outStr->printf("endobj\n");
-
-  yRef->add(rootNum + 2,0,outStr->getPos(),gTrue);
-  outStr->printf("%d 0 obj\n", rootNum + 2);
-  outStr->printf("<< ");
-  for (int n = 0; n < pageDict->getLength(); n++) {
-    if (n > 0) outStr->printf(" ");
-    const char *key = pageDict->getKey(n);
-    Object value = pageDict->getValNF(n);
-    if (strcmp(key, "Parent") == 0) {
-      outStr->printf("/Parent %d 0 R", rootNum + 1);
-    } else {
-      outStr->printf("/%s ", key);
-      writeObject(&value, outStr, getXRef(), 0, NULL, cryptRC4, 0, 0, 0);
-    }
-  }
-  outStr->printf(" >>\nendobj\n");
-
-  Goffset uxrefOffset = outStr->getPos();
-  Ref ref;
-  ref.num = rootNum;
-  ref.gen = 0;
-  Object trailerDict = createTrailerDict(rootNum + 3, gFalse, 0, &ref, getXRef(),
-                                        name->getCString(), uxrefOffset);
-  writeXRefTableTrailer(std::move(trailerDict), yRef, gFalse /* do not write unnecessary entries */,
-                        uxrefOffset, outStr, getXRef());
-
-  outStr->close();
-  fclose(f);
-  delete yRef;
-  delete countRef;
-  delete outStr;
-
-  return errNone;
-}
-
-int PDFDoc::saveAs(GooString *name, PDFWriteMode mode) {
-  FILE *f;
-  OutStream *outStr;
-  int res;
-
-  if (!(f = fopen(name->getCString(), "wb"))) {
-    error(errIO, -1, "Couldn't open file '{0:t}'", name);
-    return errOpenFile;
-  }
-  outStr = new FileOutStream(f,0);
-  res = saveAs(outStr, mode);
-  delete outStr;
-  fclose(f);
-  return res;
-}
-
-int PDFDoc::saveAs(OutStream *outStr, PDFWriteMode mode) {
-  if (!xref->isModified() && mode == writeStandard) {
-    // simply copy the original file
-    saveWithoutChangesAs (outStr);
-  } else if (mode == writeForceRewrite) {
-    saveCompleteRewrite(outStr);
-  } else {
-    saveIncrementalUpdate(outStr);
-  }
-
-  return errNone;
-}
-
-int PDFDoc::saveWithoutChangesAs(GooString *name) {
-  FILE *f;
-  OutStream *outStr;
-  int res;
-
-  if (!(f = fopen(name->getCString(), "wb"))) {
-    error(errIO, -1, "Couldn't open file '{0:t}'", name);
-    return errOpenFile;
-  }
-  
-  outStr = new FileOutStream(f,0);
-  res = saveWithoutChangesAs(outStr);
-  delete outStr;
-
-  fclose(f);
-
-  return res;
-}
-
-int PDFDoc::saveWithoutChangesAs(OutStream *outStr) {
-  int c;
-  
-  BaseStream *copyStr = str->copy();
-  copyStr->reset();
-  while ((c = copyStr->getChar()) != EOF) {
-    outStr->put(c);
-  }
-  copyStr->close();
-  delete copyStr;
-
-  return errNone;
-}
-
-void PDFDoc::saveIncrementalUpdate (OutStream* outStr)
-{
-  XRef *uxref;
-  int c;
-  //copy the original file
-  BaseStream *copyStr = str->copy();
-  copyStr->reset();
-  while ((c = copyStr->getChar()) != EOF) {
-    outStr->put(c);
-  }
-  copyStr->close();
-  delete copyStr;
-
-  Guchar *fileKey;
-  CryptAlgorithm encAlgorithm;
-  int keyLength;
-  xref->getEncryptionParameters(&fileKey, &encAlgorithm, &keyLength);
-
-  uxref = new XRef();
-  uxref->add(0, 65535, 0, gFalse);
-  xref->lock();
-  for(int i=0; i<xref->getNumObjects(); i++) {
-    if ((xref->getEntry(i)->type == xrefEntryFree) && 
-        (xref->getEntry(i)->gen == 0)) //we skip the irrelevant free objects
-      continue;
-
-    if (xref->getEntry(i)->getFlag(XRefEntry::Updated)) { //we have an updated object
-      Ref ref;
-      ref.num = i;
-      ref.gen = xref->getEntry(i)->type == xrefEntryCompressed ? 0 : xref->getEntry(i)->gen;
-      if (xref->getEntry(i)->type != xrefEntryFree) {
-        Object obj1 = xref->fetch(ref.num, ref.gen, 1);
-        Goffset offset = writeObjectHeader(&ref, outStr);
-        writeObject(&obj1, outStr, fileKey, encAlgorithm, keyLength, ref.num, ref.gen);
-        writeObjectFooter(outStr);
-        uxref->add(ref.num, ref.gen, offset, gTrue);
-      } else {
-        uxref->add(ref.num, ref.gen, 0, gFalse);
-      }
-    }
-  }
-  xref->unlock();
-  // because of "uxref->add(0, 65535, 0, gFalse);" uxref->getNumObjects() will
-  // always be >= 1; if it is 1, it means there is nothing to update
-  if (uxref->getNumObjects() == 1) {
-    delete uxref;
-    return;
-  }
-
-  Goffset uxrefOffset = outStr->getPos();
-  int numobjects = xref->getNumObjects();
-  const char *fileNameA = fileName ? fileName->getCString() : NULL;
-  Ref rootRef, uxrefStreamRef;
-  rootRef.num = getXRef()->getRootNum();
-  rootRef.gen = getXRef()->getRootGen();
-
-  // Output a xref stream if there is a xref stream already
-  GBool xRefStream = xref->isXRefStream();
-
-  if (xRefStream) {
-    // Append an entry for the xref stream itself
-    uxrefStreamRef.num = numobjects++;
-    uxrefStreamRef.gen = 0;
-    uxref->add(uxrefStreamRef.num, uxrefStreamRef.gen, uxrefOffset, gTrue);
-  }
-
-  Object trailerDict = createTrailerDict(numobjects, gTrue, getStartXRef(), &rootRef, getXRef(), fileNameA, uxrefOffset);
-  if (xRefStream) {
-    writeXRefStreamTrailer(std::move(trailerDict), uxref, &uxrefStreamRef, uxrefOffset, outStr, getXRef());
-  } else {
-    writeXRefTableTrailer(std::move(trailerDict), uxref, gFalse, uxrefOffset, outStr, getXRef());
-  }
-
-  delete uxref;
-}
-
-void PDFDoc::saveCompleteRewrite (OutStream* outStr)
-{
-  // Make sure that special flags are set, because we are going to read
-  // all objects, including Unencrypted ones.
-  xref->scanSpecialFlags();
-
-  Guchar *fileKey;
-  CryptAlgorithm encAlgorithm;
-  int keyLength;
-  xref->getEncryptionParameters(&fileKey, &encAlgorithm, &keyLength);
-
-  outStr->printf("%%PDF-%d.%d\r\n",pdfMajorVersion,pdfMinorVersion);
-  XRef *uxref = new XRef();
-  uxref->add(0, 65535, 0, gFalse);
-  xref->lock();
-  for(int i=0; i<xref->getNumObjects(); i++) {
-    Ref ref;
-    XRefEntryType type = xref->getEntry(i)->type;
-    if (type == xrefEntryFree) {
-      ref.num = i;
-      ref.gen = xref->getEntry(i)->gen;
-      /* the XRef class adds a lot of irrelevant free entries, we only want the significant one
-          and we don't want the one with num=0 because it has already been added (gen = 65535)*/
-      if (ref.gen > 0 && ref.num > 0)
-        uxref->add(ref.num, ref.gen, 0, gFalse);
-    } else if (xref->getEntry(i)->getFlag(XRefEntry::DontRewrite)) {
-      // This entry must not be written, put a free entry instead (with incremented gen)
-      ref.num = i;
-      ref.gen = xref->getEntry(i)->gen + 1;
-      uxref->add(ref.num, ref.gen, 0, gFalse);
-    } else if (type == xrefEntryUncompressed){ 
-      ref.num = i;
-      ref.gen = xref->getEntry(i)->gen;
-      Object obj1 = xref->fetch(ref.num, ref.gen, 1);
-      Goffset offset = writeObjectHeader(&ref, outStr);
-      // Write unencrypted objects in unencrypted form
-      if (xref->getEntry(i)->getFlag(XRefEntry::Unencrypted)) {
-        writeObject(&obj1, outStr, NULL, cryptRC4, 0, 0, 0);
-      } else {
-        writeObject(&obj1, outStr, fileKey, encAlgorithm, keyLength, ref.num, ref.gen);
-      }
-      writeObjectFooter(outStr);
-      uxref->add(ref.num, ref.gen, offset, gTrue);
-    } else if (type == xrefEntryCompressed) {
-      ref.num = i;
-      ref.gen = 0; //compressed entries have gen == 0
-      Object obj1 = xref->fetch(ref.num, ref.gen, 1);
-      Goffset offset = writeObjectHeader(&ref, outStr);
-      writeObject(&obj1, outStr, fileKey, encAlgorithm, keyLength, ref.num, ref.gen);
-      writeObjectFooter(outStr);
-      uxref->add(ref.num, ref.gen, offset, gTrue);
-    }
-  }
-  xref->unlock();
-  Goffset uxrefOffset = outStr->getPos();
-  writeXRefTableTrailer(uxrefOffset, uxref, gTrue /* write all entries */,
-                        uxref->getNumObjects(), outStr, gFalse /* complete rewrite */);
-  delete uxref;
-}
-
-void PDFDoc::writeDictionnary (Dict* dict, OutStream* outStr, XRef *xRef, Guint numOffset, Guchar *fileKey,
-                               CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen, std::set<Dict*> *alreadyWrittenDicts)
-{
-  bool deleteSet = false;
-  if (!alreadyWrittenDicts) {
-    alreadyWrittenDicts = new std::set<Dict*>;
-    deleteSet = true;
-  }
-
-  if (alreadyWrittenDicts->find(dict) != alreadyWrittenDicts->end()) {
-    error(errSyntaxWarning, -1, "PDFDoc::writeDictionnary: Found recursive dicts");
-    if (deleteSet) delete alreadyWrittenDicts;
-    return;
-  } else {
-    alreadyWrittenDicts->insert(dict);
-  }
-
-  outStr->printf("<<");
-  for (int i=0; i<dict->getLength(); i++) {
-    GooString keyName(dict->getKey(i));
-    GooString *keyNameToPrint = keyName.sanitizedName(gFalse /* non ps mode */);
-    outStr->printf("/%s ", keyNameToPrint->getCString());
-    delete keyNameToPrint;
-    Object obj1 = dict->getValNF(i);
-    writeObject(&obj1, outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
-  }
-  outStr->printf(">> ");
-
-  if (deleteSet) {
-    delete alreadyWrittenDicts;
-  }
-}
-
-void PDFDoc::writeStream (Stream* str, OutStream* outStr)
-{
-  outStr->printf("stream\r\n");
-  str->reset();
-  for (int c=str->getChar(); c!= EOF; c=str->getChar()) {
-    outStr->printf("%c", c);  
-  }
-  outStr->printf("\r\nendstream\r\n");
-}
-
-void PDFDoc::writeRawStream (Stream* str, OutStream* outStr)
-{
-  Object obj1 = str->getDict()->lookup("Length");
-  if (!obj1.isInt() && !obj1.isInt64()) {
-    error (errSyntaxError, -1, "PDFDoc::writeRawStream, no Length in stream dict");
-    return;
-  }
-
-  Goffset length;
-  if (obj1.isInt())
-    length = obj1.getInt();
-  else
-    length = obj1.getInt64();
-
-  outStr->printf("stream\r\n");
-  str->unfilteredReset();
-  for (Goffset i = 0; i < length; i++) {
-    int c = str->getUnfilteredChar();
-    if (unlikely(c == EOF)) {
-      error (errSyntaxError, -1, "PDFDoc::writeRawStream: EOF reading stream");
-      break;
-    }
-    outStr->printf("%c", c);  
-  }
-  str->reset();
-  outStr->printf("\r\nendstream\r\n");
-}
-
-void PDFDoc::writeString (GooString* s, OutStream* outStr, Guchar *fileKey,
-                          CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen)
-{
-  // Encrypt string if encryption is enabled
-  GooString *sEnc = NULL;
-  if (fileKey) {
-    EncryptStream *enc = new EncryptStream(new MemStream(s->getCString(), 0, s->getLength(), Object(objNull)),
-                                           fileKey, encAlgorithm, keyLength, objNum, objGen);
-    sEnc = new GooString();
-    int c;
-    enc->reset();
-    while ((c = enc->getChar()) != EOF) {
-      sEnc->append((char)c);
-    }
-
-    delete enc;
-    s = sEnc;
-  }
-
-  // Write data
-  if (s->hasUnicodeMarker()) {
-    //unicode string don't necessary end with \0
-    const char* c = s->getCString();
-    outStr->printf("(");
-    for(int i=0; i<s->getLength(); i++) {
-      char unescaped = *(c+i)&0x000000ff;
-      //escape if needed
-      if (unescaped == '(' || unescaped == ')' || unescaped == '\\')
-        outStr->printf("%c", '\\');
-      outStr->printf("%c", unescaped);
-    }
-    outStr->printf(") ");
-  } else {
-    const char* c = s->getCString();
-    outStr->printf("(");
-    for(int i=0; i<s->getLength(); i++) {
-      char unescaped = *(c+i)&0x000000ff;
-      //escape if needed
-      if (unescaped == '\r')
-        outStr->printf("\\r");
-      else if (unescaped == '\n')
-        outStr->printf("\\n");
-      else {
-        if (unescaped == '(' || unescaped == ')' || unescaped == '\\') {
-          outStr->printf("%c", '\\');
-        }
-        outStr->printf("%c", unescaped);
-      }
-    }
-    outStr->printf(") ");
-  }
-
-  delete sEnc;
-}
-
-Goffset PDFDoc::writeObjectHeader (Ref *ref, OutStream* outStr)
-{
-  Goffset offset = outStr->getPos();
-  outStr->printf("%i %i obj ", ref->num, ref->gen);
-  return offset;
-}
-
-void PDFDoc::writeObject (Object* obj, OutStream* outStr, XRef *xRef, Guint numOffset, Guchar *fileKey,
-                          CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen, std::set<Dict*> *alreadyWrittenDicts)
-{
-  Array *array;
-
-  switch (obj->getType()) {
-    case objBool:
-      outStr->printf("%s ", obj->getBool()?"true":"false");
-      break;
-    case objInt:
-      outStr->printf("%i ", obj->getInt());
-      break;
-    case objInt64:
-      outStr->printf("%lli ", obj->getInt64());
-      break;
-    case objReal:
-    {
-      GooString s;
-      s.appendf("{0:.10g}", obj->getReal());
-      outStr->printf("%s ", s.getCString());
-      break;
-    }
-    case objString:
-      writeString(obj->getString(), outStr, fileKey, encAlgorithm, keyLength, objNum, objGen);
-      break;
-    case objName:
-    {
-      GooString name(obj->getName());
-      GooString *nameToPrint = name.sanitizedName(gFalse /* non ps mode */);
-      outStr->printf("/%s ", nameToPrint->getCString());
-      delete nameToPrint;
-      break;
-    }
-    case objNull:
-      outStr->printf( "null ");
-      break;
-    case objArray:
-      array = obj->getArray();
-      outStr->printf("[");
-      for (int i=0; i<array->getLength(); i++) {
-	Object obj1 = array->getNF(i);
-        writeObject(&obj1, outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen);
-      }
-      outStr->printf("] ");
-      break;
-    case objDict:
-      writeDictionnary (obj->getDict(), outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
-      break;
-    case objStream: 
-      {
-        //We can't modify stream with the current implementation (no write functions in Stream API)
-        // => the only type of streams which that have been modified are internal streams (=strWeird)
-        Stream *stream = obj->getStream();
-        if (stream->getKind() == strWeird || stream->getKind() == strCrypt) {
-          //we write the stream unencoded => TODO: write stream encoder
-
-          // Encrypt stream
-          EncryptStream *encStream = NULL;
-          GBool removeFilter = gTrue;
-          if (stream->getKind() == strWeird && fileKey) {
-            Object filter = stream->getDict()->lookup("Filter");
-            if (!filter.isName("Crypt")) {
-              if (filter.isArray()) {
-                for (int i = 0; i < filter.arrayGetLength(); i++) {
-                  Object filterEle = filter.arrayGet(i);
-                  if (filterEle.isName("Crypt")) {
-                    removeFilter = gFalse;
-                    break;
-                  }
-                }
-                if (removeFilter) {
-                  encStream = new EncryptStream(stream, fileKey, encAlgorithm, keyLength, objNum, objGen);
-                  encStream->setAutoDelete(gFalse);
-                  stream = encStream;
-                }
-              } else {
-                encStream = new EncryptStream(stream, fileKey, encAlgorithm, keyLength, objNum, objGen);
-                encStream->setAutoDelete(gFalse);
-                stream = encStream;
-              }
-            } else {
-              removeFilter = gFalse;
-            }
-          } else if (fileKey != NULL) { // Encrypt stream
-            encStream = new EncryptStream(stream, fileKey, encAlgorithm, keyLength, objNum, objGen);
-            encStream->setAutoDelete(gFalse);
-            stream = encStream;
-          }
-
-          stream->reset();
-          //recalculate stream length
-          Goffset tmp = 0;
-          for (int c=stream->getChar(); c!=EOF; c=stream->getChar()) {
-            tmp++;
-          }
-          stream->getDict()->set("Length", Object(tmp));
-
-          //Remove Stream encoding
-          if (removeFilter) {
-            stream->getDict()->remove("Filter");
-          }
-          stream->getDict()->remove("DecodeParms");
-
-          writeDictionnary (stream->getDict(),outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
-          writeStream (stream,outStr);
-          delete encStream;
-        } else {
-          //raw stream copy
-          FilterStream *fs = dynamic_cast<FilterStream*>(stream);
-          if (fs) {
-            BaseStream *bs = fs->getBaseStream();
-            if (bs) {
-              Goffset streamEnd;
-                if (xRef->getStreamEnd(bs->getStart(), &streamEnd)) {
-                  Goffset val = streamEnd - bs->getStart();
-                  stream->getDict()->set("Length", Object(val));
-                }
-              }
-          }
-          writeDictionnary (stream->getDict(), outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
-          writeRawStream (stream, outStr);
-        }
-        break;
-      }
-    case objRef:
-      outStr->printf("%i %i R ", obj->getRef().num + numOffset, obj->getRef().gen);
-      break;
-    case objCmd:
-      outStr->printf("%s\n", obj->getCmd());
-      break;
-    case objError:
-      outStr->printf("error\r\n");
-      break;
-    case objEOF:
-      outStr->printf("eof\r\n");
-      break;
-    case objNone:
-      outStr->printf("none\r\n");
-      break;
-    default:
-      error(errUnimplemented, -1,"Unhandled objType : {0:d}, please report a bug with a testcase\r\n", obj->getType());
-      break;
-  }
-}
-
-void PDFDoc::writeObjectFooter (OutStream* outStr)
-{
-  outStr->printf("endobj\r\n");
-}
-
-Object PDFDoc::createTrailerDict(int uxrefSize, GBool incrUpdate, Goffset startxRef,
-                                Ref *root, XRef *xRef, const char *fileName, Goffset fileSize)
-{
-  Dict *trailerDict = new Dict(xRef);
-  trailerDict->set("Size", Object(uxrefSize));
-
-  //build a new ID, as recommended in the reference, uses:
-  // - current time
-  // - file name
-  // - file size
-  // - values of entry in information dictionnary
-  GooString message;
-  char buffer[256];
-  sprintf(buffer, "%i", (int)time(NULL));
-  message.append(buffer);
-
-  if (fileName)
-    message.append(fileName);
-
-  sprintf(buffer, "%lli", (long long)fileSize);
-  message.append(buffer);
-
-  //info dict -- only use text string
-  if (!xRef->getTrailerDict()->isNone()) {
-    Object docInfo = xRef->getDocInfo();
-    if (docInfo.isDict()) {
-      for(int i=0; i<docInfo.getDict()->getLength(); i++) {
-        Object obj2 = docInfo.getDict()->getVal(i);
-        if (obj2.isString()) {
-          message.append(obj2.getString());
-        }
-      }
-    }
-  }
-
-  GBool hasEncrypt = gFalse;
-  if (!xRef->getTrailerDict()->isNone()) {
-    Object obj2 = xRef->getTrailerDict()->dictLookupNF("Encrypt");
-    if (!obj2.isNull()) {
-      trailerDict->set("Encrypt", std::move(obj2));
-      hasEncrypt = gTrue;
-    }
-  }
-
-  //calculate md5 digest
-  Guchar digest[16];
-  md5((Guchar*)message.getCString(), message.getLength(), digest);
-
-  //create ID array
-  // In case of encrypted files, the ID must not be changed because it's used to calculate the key
-  if (incrUpdate || hasEncrypt) {
-    //only update the second part of the array
-    Object obj4  = xRef->getTrailerDict()->getDict()->lookup("ID");
-    if (!obj4.isArray()) {
-      error(errSyntaxWarning, -1, "PDFDoc::createTrailerDict original file's ID entry isn't an array. Trying to continue");
-    } else {
-      Array *array = new Array(xRef);
-      //Get the first part of the ID
-      array->add(obj4.arrayGet(0));
-      array->add(Object(new GooString((const char*)digest, 16)));
-      trailerDict->set("ID", Object(array));
-    }
-  } else {
-    //new file => same values for the two identifiers
-    Array *array = new Array(xRef);
-    array->add(Object(new GooString((const char*)digest, 16)));
-    array->add(Object(new GooString((const char*)digest, 16)));
-    trailerDict->set("ID", Object(array));
-  }
-
-  trailerDict->set("Root", Object(root->num, root->gen));
-
-  if (incrUpdate) { 
-    trailerDict->set("Prev", Object(startxRef));
-  }
-  
-  if (!xRef->getTrailerDict()->isNone()) {
-    Object obj5 = xRef->getDocInfoNF();
-    if (!obj5.isNull()) {
-      trailerDict->set("Info", std::move(obj5));
-    }
-  }
-
-  return Object(trailerDict);
-}
-
-void PDFDoc::writeXRefTableTrailer(Object &&trailerDict, XRef *uxref, GBool writeAllEntries, Goffset uxrefOffset, OutStream* outStr, XRef *xRef)
-{
-  uxref->writeTableToFile( outStr, writeAllEntries );
-  outStr->printf( "trailer\r\n");
-  writeDictionnary(trailerDict.getDict(), outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0, nullptr);
-  outStr->printf( "\r\nstartxref\r\n");
-  outStr->printf( "%lli\r\n", uxrefOffset);
-  outStr->printf( "%%%%EOF\r\n");
-}
-
-void PDFDoc::writeXRefStreamTrailer (Object &&trailerDict, XRef *uxref, Ref *uxrefStreamRef, Goffset uxrefOffset, OutStream* outStr, XRef *xRef)
-{
-  GooString stmData;
-
-  // Fill stmData and some trailerDict fields
-  uxref->writeStreamToBuffer(&stmData, trailerDict.getDict(), xRef);
-
-  // Create XRef stream object and write it
-  MemStream *mStream = new MemStream( stmData.getCString(), 0, stmData.getLength(), std::move(trailerDict) );
-  writeObjectHeader(uxrefStreamRef, outStr);
-  Object obj1(static_cast<Stream*>(mStream));
-  writeObject(&obj1, outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0);
-  writeObjectFooter(outStr);
-
-  outStr->printf( "startxref\r\n");
-  outStr->printf( "%lli\r\n", uxrefOffset);
-  outStr->printf( "%%%%EOF\r\n");
-}
-
-void PDFDoc::writeXRefTableTrailer(Goffset uxrefOffset, XRef *uxref, GBool writeAllEntries,
-                                   int uxrefSize, OutStream* outStr, GBool incrUpdate)
-{
-  const char *fileNameA = fileName ? fileName->getCString() : NULL;
-  // file size (doesn't include the trailer)
-  unsigned int fileSize = 0;
-  int c;
-  str->reset();
-  while ((c = str->getChar()) != EOF) {
-    fileSize++;
-  }
-  str->close();
-  Ref ref;
-  ref.num = getXRef()->getRootNum();
-  ref.gen = getXRef()->getRootGen();
-  Object trailerDict = createTrailerDict(uxrefSize, incrUpdate, getStartXRef(), &ref,
-                                         getXRef(), fileNameA, fileSize);
-  writeXRefTableTrailer(std::move(trailerDict), uxref, writeAllEntries, uxrefOffset, outStr, getXRef());
-}
-
-void PDFDoc::writeHeader(OutStream *outStr, int major, int minor)
-{
-   outStr->printf("%%PDF-%d.%d\n", major, minor);
-   outStr->printf("%%\xE2\xE3\xCF\xD3\n");
-}
-
-void PDFDoc::markDictionnary (Dict* dict, XRef * xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts)
-{
-  bool deleteSet = false;
-  if (!alreadyMarkedDicts) {
-    alreadyMarkedDicts = new std::set<Dict*>;
-    deleteSet = true;
-  }
-
-  if (alreadyMarkedDicts->find(dict) != alreadyMarkedDicts->end()) {
-    error(errSyntaxWarning, -1, "PDFDoc::markDictionnary: Found recursive dicts");
-    if (deleteSet) delete alreadyMarkedDicts;
-    return;
-  } else {
-    alreadyMarkedDicts->insert(dict);
-  }
-
-  Object obj1;
-  for (int i=0; i<dict->getLength(); i++) {
-    const char *key = dict->getKey(i);
-    if (strcmp(key, "Annots") != 0) {
-      Object obj1 = dict->getValNF(i);
-      markObject(&obj1, xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
-    } else {
-      Object annotsObj = dict->getValNF(i);
-      if (!annotsObj.isNull()) {
-        markAnnotations(&annotsObj, xRef, countRef, 0, oldRefNum, newRefNum, alreadyMarkedDicts);
-      }
-    }
-  }
-
-  if (deleteSet) {
-    delete alreadyMarkedDicts;
-  }
-}
-
-void PDFDoc::markObject (Object* obj, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts)
-{
-  Array *array;
-
-  switch (obj->getType()) {
-    case objArray:
-      array = obj->getArray();
-      for (int i=0; i<array->getLength(); i++) {
-        Object obj1 = array->getNF(i);
-        markObject(&obj1, xRef, countRef, numOffset, oldRefNum, newRefNum);
-      }
-      break;
-    case objDict:
-      markDictionnary (obj->getDict(), xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
-      break;
-    case objStream: 
-      {
-        Stream *stream = obj->getStream();
-        markDictionnary (stream->getDict(), xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
-      }
-      break;
-    case objRef:
-      {
-        if (obj->getRef().num + (int) numOffset >= xRef->getNumObjects() || xRef->getEntry(obj->getRef().num + numOffset)->type == xrefEntryFree) {
-          if (getXRef()->getEntry(obj->getRef().num)->type == xrefEntryFree) {
-            return;  // already marked as free => should be replaced
-          }
-          xRef->add(obj->getRef().num + numOffset, obj->getRef().gen, 0, gTrue);
-          if (getXRef()->getEntry(obj->getRef().num)->type == xrefEntryCompressed) {
-            xRef->getEntry(obj->getRef().num + numOffset)->type = xrefEntryCompressed;
-          }
-        }
-        if (obj->getRef().num + (int) numOffset >= countRef->getNumObjects() || 
-            countRef->getEntry(obj->getRef().num + numOffset)->type == xrefEntryFree)
-        {
-          countRef->add(obj->getRef().num + numOffset, 1, 0, gTrue);
-        } else {
-          XRefEntry *entry = countRef->getEntry(obj->getRef().num + numOffset);
-          entry->gen++;
-          if (entry->gen > 9)
-            break;
-        } 
-        Object obj1 = getXRef()->fetch(obj->getRef().num, obj->getRef().gen);
-        markObject(&obj1, xRef, countRef, numOffset, oldRefNum, newRefNum);
-      }
-      break;
-    default:
-      break;
-  }
-}
-
-void PDFDoc::replacePageDict(int pageNo, int rotate,
-                             PDFRectangle *mediaBox, 
-                             PDFRectangle *cropBox)
-{
-  Ref *refPage = getCatalog()->getPageRef(pageNo);
-  Object page = getXRef()->fetch(refPage->num, refPage->gen);
-  Dict *pageDict = page.getDict();
-  pageDict->remove("MediaBoxssdf");
-  pageDict->remove("MediaBox");
-  pageDict->remove("CropBox");
-  pageDict->remove("ArtBox");
-  pageDict->remove("BleedBox");
-  pageDict->remove("TrimBox");
-  pageDict->remove("Rotate");
-  Array *mediaBoxArray = new Array(getXRef());
-  mediaBoxArray->add(Object(mediaBox->x1));
-  mediaBoxArray->add(Object(mediaBox->y1));
-  mediaBoxArray->add(Object(mediaBox->x2));
-  mediaBoxArray->add(Object(mediaBox->y2));
-  Object mediaBoxObject(mediaBoxArray);
-  Object trimBoxObject = mediaBoxObject.copy();
-  pageDict->add(copyString("MediaBox"), std::move(mediaBoxObject));
-  if (cropBox != NULL) {
-    Array *cropBoxArray = new Array(getXRef());
-    cropBoxArray->add(Object(cropBox->x1));
-    cropBoxArray->add(Object(cropBox->y1));
-    cropBoxArray->add(Object(cropBox->x2));
-    cropBoxArray->add(Object(cropBox->y2));
-    Object cropBoxObject(cropBoxArray);
-    trimBoxObject = cropBoxObject.copy();
-    pageDict->add(copyString("CropBox"), std::move(cropBoxObject));
-  }
-  pageDict->add(copyString("TrimBox"), std::move(trimBoxObject));
-  pageDict->add(copyString("Rotate"), Object(rotate));
-  getXRef()->setModifiedObject(&page, *refPage);
-}
-
-void PDFDoc::markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts)
-{
-  pageDict->remove("OpenAction");
-  pageDict->remove("Outlines");
-  pageDict->remove("StructTreeRoot");
-
-  for (int n = 0; n < pageDict->getLength(); n++) {
-    const char *key = pageDict->getKey(n);
-    Object value  = pageDict->getValNF(n);
-    if (strcmp(key, "Parent") != 0 &&
-	      strcmp(key, "Pages") != 0 &&
-	      strcmp(key, "AcroForm") != 0 &&
-	      strcmp(key, "Annots") != 0 &&
-	      strcmp(key, "P") != 0 &&
-        strcmp(key, "Root") != 0) {
-      markObject(&value, xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
-    }
-  }
-}
-
-GBool PDFDoc::markAnnotations(Object *annotsObj, XRef *xRef, XRef *countRef, Guint numOffset, int oldPageNum, int newPageNum, std::set<Dict*> *alreadyMarkedDicts) {
-  GBool modified = gFalse;
-  Object annots = annotsObj->fetch(getXRef());
-  if (annots.isArray()) {
-      Array *array = annots.getArray();
-      for (int i=array->getLength() - 1; i >= 0; i--) {
-        Object obj1 = array->get(i);
-        if (obj1.isDict()) {
-          Dict *dict = obj1.getDict();
-          Object type = dict->lookup("Type");
-          if (type.isName() && strcmp(type.getName(), "Annot") == 0) {
-            Object obj2 = dict->lookupNF("P");
-            if (obj2.isRef()) {
-              if (obj2.getRef().num == oldPageNum) {
-                Object obj3 = array->getNF(i);
-                if (obj3.isRef()) {
-                  dict->set("P", Object(newPageNum, 0));
-                  getXRef()->setModifiedObject(&obj1, obj3.getRef());
-                }
-              } else if (obj2.getRef().num == newPageNum) {
-                continue;
-              } else {
-                Object page  = getXRef()->fetch(obj2.getRef().num, obj2.getRef().gen);
-                if (page.isDict()) {
-                  Dict *dict = page.getDict();
-                  Object pagetype = dict->lookup("Type");
-                  if (!pagetype.isName() || strcmp(pagetype.getName(), "Page") != 0) {
-                    continue;
-                  }
-                }
-                array->remove(i);
-                modified = gTrue;
-                continue;
-              }
-            }
-          }
-          markPageObjects(dict, xRef, countRef, numOffset, oldPageNum, newPageNum, alreadyMarkedDicts);
-        }
-        obj1 = array->getNF(i);
-        if (obj1.isRef()) {
-          if (obj1.getRef().num + (int) numOffset >= xRef->getNumObjects() || xRef->getEntry(obj1.getRef().num + numOffset)->type == xrefEntryFree) {
-            if (getXRef()->getEntry(obj1.getRef().num)->type == xrefEntryFree) {
-              continue;  // already marked as free => should be replaced
-            }
-            xRef->add(obj1.getRef().num + numOffset, obj1.getRef().gen, 0, gTrue);
-            if (getXRef()->getEntry(obj1.getRef().num)->type == xrefEntryCompressed) {
-              xRef->getEntry(obj1.getRef().num + numOffset)->type = xrefEntryCompressed;
-            }
-          }
-          if (obj1.getRef().num + (int) numOffset >= countRef->getNumObjects() || 
-              countRef->getEntry(obj1.getRef().num + numOffset)->type == xrefEntryFree)
-          {
-            countRef->add(obj1.getRef().num + numOffset, 1, 0, gTrue);
-          } else {
-            XRefEntry *entry = countRef->getEntry(obj1.getRef().num + numOffset);
-            entry->gen++;
-          } 
-        }
-      }
-  }
-  if (annotsObj->isRef()) {
-    if (annotsObj->getRef().num + (int) numOffset >= xRef->getNumObjects() || xRef->getEntry(annotsObj->getRef().num + numOffset)->type == xrefEntryFree) {
-      if (getXRef()->getEntry(annotsObj->getRef().num)->type == xrefEntryFree) {
-        return modified;  // already marked as free => should be replaced
-      }
-      xRef->add(annotsObj->getRef().num + numOffset, annotsObj->getRef().gen, 0, gTrue);
-      if (getXRef()->getEntry(annotsObj->getRef().num)->type == xrefEntryCompressed) {
-        xRef->getEntry(annotsObj->getRef().num + numOffset)->type = xrefEntryCompressed;
-      }
-    }
-    if (annotsObj->getRef().num + (int) numOffset >= countRef->getNumObjects() || 
-        countRef->getEntry(annotsObj->getRef().num + numOffset)->type == xrefEntryFree)
-    {
-      countRef->add(annotsObj->getRef().num + numOffset, 1, 0, gTrue);
-    } else {
-      XRefEntry *entry = countRef->getEntry(annotsObj->getRef().num + numOffset);
-      entry->gen++;
-    } 
-    getXRef()->setModifiedObject(&annots, annotsObj->getRef());
-  }
-  return modified;
-}
-
-void PDFDoc::markAcroForm(Object *afObj, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum) {
-  GBool modified = gFalse;
-  Object acroform = afObj->fetch(getXRef());
-  if (acroform.isDict()) {
-      Dict *dict = acroform.getDict();
-      for (int i=0; i < dict->getLength(); i++) {
-        if (strcmp(dict->getKey(i), "Fields") == 0) {
-          Object fields = dict->getValNF(i);
-          modified = markAnnotations(&fields, xRef, countRef, numOffset, oldRefNum, newRefNum);
-        } else {
-          Object obj = dict->getValNF(i);
-          markObject(&obj, xRef, countRef, numOffset, oldRefNum, newRefNum);
-        }
-      }
-  }
-  if (afObj->isRef()) {
-    if (afObj->getRef().num + (int) numOffset >= xRef->getNumObjects() || xRef->getEntry(afObj->getRef().num + numOffset)->type == xrefEntryFree) {
-      if (getXRef()->getEntry(afObj->getRef().num)->type == xrefEntryFree) {
-        return;  // already marked as free => should be replaced
-      }
-      xRef->add(afObj->getRef().num + numOffset, afObj->getRef().gen, 0, gTrue);
-      if (getXRef()->getEntry(afObj->getRef().num)->type == xrefEntryCompressed) {
-        xRef->getEntry(afObj->getRef().num + numOffset)->type = xrefEntryCompressed;
-      }
-    }
-    if (afObj->getRef().num + (int) numOffset >= countRef->getNumObjects() || 
-        countRef->getEntry(afObj->getRef().num + numOffset)->type == xrefEntryFree)
-    {
-      countRef->add(afObj->getRef().num + numOffset, 1, 0, gTrue);
-    } else {
-      XRefEntry *entry = countRef->getEntry(afObj->getRef().num + numOffset);
-      entry->gen++;
-    } 
-    if (modified){
-      getXRef()->setModifiedObject(&acroform, afObj->getRef());
-    }
-  }
-  return;
-}
-
-Guint PDFDoc::writePageObjects(OutStream *outStr, XRef *xRef, Guint numOffset, GBool combine) 
-{
-  Guint objectsCount = 0; //count the number of objects in the XRef(s)
-  Guchar *fileKey;
-  CryptAlgorithm encAlgorithm;
-  int keyLength;
-  xRef->getEncryptionParameters(&fileKey, &encAlgorithm, &keyLength);
-
-  for (int n = numOffset; n < xRef->getNumObjects(); n++) {
-    if (xRef->getEntry(n)->type != xrefEntryFree) {
-      Ref ref;
-      ref.num = n;
-      ref.gen = xRef->getEntry(n)->gen;
-      objectsCount++;
-      Object obj = getXRef()->fetch(ref.num - numOffset, ref.gen);
-      Goffset offset = writeObjectHeader(&ref, outStr);
-      if (combine) {
-        writeObject(&obj, outStr, getXRef(), numOffset, NULL, cryptRC4, 0, 0, 0);
-      } else if (xRef->getEntry(n)->getFlag(XRefEntry::Unencrypted)) {
-        writeObject(&obj, outStr, NULL, cryptRC4, 0, 0, 0);
-      } else {
-        writeObject(&obj, outStr, fileKey, encAlgorithm, keyLength, ref.num, ref.gen);
-      }
-      writeObjectFooter(outStr);
-      xRef->add(ref.num, ref.gen, offset, gTrue);
-    }
-  }
-  return objectsCount;
-}
-
-#ifndef DISABLE_OUTLINE
-Outline *PDFDoc::getOutline()
-{
-  if (!outline) {
-    pdfdocLocker();
-    // read outline
-    outline = new Outline(catalog->getOutline(), xref);
-  }
-
-  return outline;
-}
-#endif
-
-PDFDoc *PDFDoc::ErrorPDFDoc(int errorCode, GooString *fileNameA)
-{
-  PDFDoc *doc = new PDFDoc();
-  doc->errCode = errorCode;
-  doc->fileName = fileNameA;
-
-  return doc;
-}
-
-long long PDFDoc::strToLongLong(char *s) {
-  long long x, d;
-  char *p;
-
-  x = 0;
-  for (p = s; *p && isdigit(*p & 0xff); ++p) {
-    d = *p - '0';
-    if (x > (LLONG_MAX - d) / 10) {
-      break;
-    }
-    x = 10 * x + d;
-  }
-  return x;
-}
-
-// Read the 'startxref' position.
-Goffset PDFDoc::getStartXRef(GBool tryingToReconstruct)
-{
-  if (startXRefPos == -1) {
-
-    if (isLinearized(tryingToReconstruct)) {
-      char buf[linearizationSearchSize+1];
-      int c, n, i;
-
-      str->setPos(0);
-      for (n = 0; n < linearizationSearchSize; ++n) {
-        if ((c = str->getChar()) == EOF) {
-          break;
-        }
-        buf[n] = c;
-      }
-      buf[n] = '\0';
-
-      // find end of first obj (linearization dictionary)
-      startXRefPos = 0;
-      for (i = 0; i < n; i++) {
-        if (!strncmp("endobj", &buf[i], 6)) {
-	  i += 6;
-	  //skip whitespace 
-	  while (buf[i] && Lexer::isSpace(buf[i])) ++i;
-	  startXRefPos = i;
-	  break;
-        }
-      }
-    } else {
-      char buf[xrefSearchSize+1];
-      char *p;
-      int c, n, i;
-
-      // read last xrefSearchSize bytes
-      int segnum = 0;
-      int maxXRefSearch = 24576;
-      if (str->getLength() < maxXRefSearch) maxXRefSearch = str->getLength();
-      for (; (xrefSearchSize - 16) * segnum < maxXRefSearch; segnum++) {
-        str->setPos((xrefSearchSize - 16) * segnum + xrefSearchSize, -1);
-        for (n = 0; n < xrefSearchSize; ++n) {
-          if ((c = str->getChar()) == EOF) {
-            break;
-          }
-          buf[n] = c;
-        }
-        buf[n] = '\0';
-
-        // find startxref
-        for (i = n - 9; i >= 0; --i) {
-          if (!strncmp(&buf[i], "startxref", 9)) {
-            break;
-          }
-        }
-        if (i < 0) {
-          startXRefPos = 0;
-        } else {
-          for (p = &buf[i + 9]; isspace(*p); ++p);
-          startXRefPos = strToLongLong(p);
-          break;
-        }
-      }
-    }
-
-  }
-
-  return startXRefPos;
-}
-
-Goffset PDFDoc::getMainXRefEntriesOffset(GBool tryingToReconstruct)
-{
-  Guint mainXRefEntriesOffset = 0;
-
-  if (isLinearized(tryingToReconstruct)) {
-    mainXRefEntriesOffset = getLinearization()->getMainXRefEntriesOffset();
-  }
-
-  return mainXRefEntriesOffset;
-}
-
-int PDFDoc::getNumPages()
-{
-  if (isLinearized()) {
-    int n;
-    if ((n = getLinearization()->getNumPages())) {
-      return n;
-    }
-  }
-
-  return catalog->getNumPages();
-}
-
-Page *PDFDoc::parsePage(int page)
-{
-  Ref pageRef;
-
-  pageRef.num = getHints()->getPageObjectNum(page);
-  if (!pageRef.num) {
-    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(errSyntaxWarning, -1, "Invalid object num ({0:d}) for page {1:d}", pageRef.num, page);
-    return NULL;
-  }
-
-  pageRef.gen = xref->getEntry(pageRef.num)->gen;
-  Object obj = xref->fetch(pageRef.num, pageRef.gen);
-  if (!obj.isDict("Page")) {
-    error(errSyntaxWarning, -1, "Object ({0:d} {1:d}) is not a pageDict", pageRef.num, pageRef.gen);
-    return NULL;
-  }
-  Dict *pageDict = obj.getDict();
-
-  return new Page(this, page, &obj, pageRef,
-               new PageAttrs(NULL, pageDict), catalog->getForm());
-}
-
-Page *PDFDoc::getPage(int page)
-{
-  if ((page < 1) || page > getNumPages()) return NULL;
-
-  if (isLinearized() && checkLinearization()) {
-    pdfdocLocker();
-    if (!pageCache) {
-      pageCache = (Page **) gmallocn(getNumPages(), sizeof(Page *));
-      for (int i = 0; i < getNumPages(); i++) {
-        pageCache[i] = NULL;
-      }
-    }
-    if (!pageCache[page-1]) {
-      pageCache[page-1] = parsePage(page);
-    }
-    if (pageCache[page-1]) {
-       return pageCache[page-1];
-    } else {
-       error(errSyntaxWarning, -1, "Failed parsing page {0:d} using hint tables", page);
-    }
-  }
-
-  return catalog->getPage(page);
-}
-- 
GitLab