...
 
Commits (12)
......@@ -314,6 +314,8 @@ configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
configure_file(poppler/poppler-config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/poppler/poppler-config.h)
set(poppler_SRCS
goo/gbase64.cc
goo/gbasename.cc
goo/gfile.cc
goo/GooTimer.cc
goo/GooString.cc
......
......@@ -217,7 +217,7 @@ OPTIMIZE_OUTPUT_VHDL = NO
# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
EXTENSION_MAPPING =
EXTENSION_MAPPING = in=C++
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
# to include (a tag file for) the STL sources as input, then you should
......
......@@ -16,6 +16,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
\file poppler-destination.h
*/
#include "poppler-destination.h"
#include "poppler-destination-private.h"
......
......@@ -20,6 +20,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
\file poppler-document.h
*/
#include "poppler-destination.h"
#include "poppler-document.h"
#include "poppler-embedded-file.h"
......
......@@ -18,6 +18,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
\file poppler-embedded-file.h
*/
#include "poppler-embedded-file.h"
#include "poppler-embedded-file-private.h"
......
......@@ -18,6 +18,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
\file poppler-font.h
*/
#include "poppler-font.h"
#include "poppler-document-private.h"
......
......@@ -23,6 +23,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
\file poppler-global.h
*/
#include "poppler-global.h"
#include "poppler-private.h"
......
......@@ -21,6 +21,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
\file poppler-image.h
*/
#include "poppler-image.h"
#include "poppler-image-private.h"
......
......@@ -18,6 +18,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
\file poppler-page-renderer.h
*/
#include "poppler-page-renderer.h"
#include "poppler-document-private.h"
......
......@@ -17,6 +17,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
\file poppler-page-transition.h
*/
#include "poppler-page-transition.h"
#include "PageTransition.h"
......
......@@ -22,6 +22,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
\file poppler-page.h
*/
#include "poppler-page.h"
#include "poppler-page-transition.h"
......
......@@ -16,6 +16,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
\file poppler-rectangle.h
*/
#include "poppler-rectangle.h"
#include <iostream>
......
......@@ -17,6 +17,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
\file poppler-toc.h
*/
#include "poppler-toc.h"
#include "poppler-toc-private.h"
......
......@@ -16,8 +16,35 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
\file poppler-version.h.in
\brief poppler-version.h
\remark poppler-version.h.in is the file name in Poppler's source files.
The file name as an include file is poppler-version.h.
*/
#include "poppler-version.h"
/**
\def POPPLER_VERSION
\brief The version string of the poppler-cpp header files.
e.g. in poppler version 0.1.2 this is "0.1.2".
*/
/**
\def POPPLER_VERSION_MAJOR
\brief The "major" version number of the poppler-cpp header files.
e.g. in poppler version 0.1.2 this is 0.
*/
/**
\def POPPLER_VERSION_MINOR
\brief The "minor" version number of the poppler-cpp header files.
e.g. in poppler version 0.1.2 this is 1.
*/
/**
\def POPPLER_VERSION_MICRO
\brief The "micro" version number of the poppler-cpp header files.
e.g. in poppler version 0.1.2 this is 2.
*/
using namespace poppler;
/**
......
......@@ -435,7 +435,7 @@ find_annot_movie_for_action (PopplerDocument *document,
if (link->hasAnnotRef ()) {
const Ref *ref = link->getAnnotRef ();
annotObj = xref->fetch (ref->num, ref->gen);
annotObj = xref->fetch (*ref);
} else if (link->hasAnnotTitle ()) {
const GooString *title = link->getAnnotTitle ();
int i;
......
//========================================================================
//
// gbase64.cc
//
// Implementation of a base64 encoder, because another one did not immediately
// avail itself.
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2018 Greg Knight <lyngvi@gmail.com>
//
//========================================================================
#include "gbase64.h"
#include <sstream>
static void b64encodeTriplet(char output[4], unsigned char a, unsigned char b, unsigned char c)
{
static const char* base64table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
output[0] = base64table[((a >> 2) & 0x3f) ]; // upper 6 of first byte
output[1] = base64table[((a << 4) & 0x30) | ((b >> 4) & 0x0f)]; // lower 2 of first byte, upper 4 of second byte
output[2] = base64table[((b << 2) & 0x3c) | ((c >> 6) & 0x03)]; // lower 4 of second byte, upper 2 of third byte
output[3] = base64table[((c ) & 0x3f)]; // lower 6 of third byte
}
std::string gbase64Encode(const void* input, size_t len)
{
char quad[4];
size_t pos = 0;
std::stringstream buf;
auto bytes = static_cast<const unsigned char*>(input);
for ( ; pos + 3 <= len; pos += 3) {
b64encodeTriplet(quad, bytes[0], bytes[1], bytes[2]);
buf.write(&quad[0], 4);
bytes += 3;
}
switch (len - pos) {
case 1:
b64encodeTriplet(quad, bytes[0], 0, 0);
quad[2] = quad[3] = '=';
buf.write(&quad[0], 4);
break;
case 2:
b64encodeTriplet(quad, bytes[0], bytes[1], 0);
quad[3] = '=';
buf.write(&quad[0], 4);
break;
}
return buf.str();
}
//========================================================================
//
// gbase64.h
//
// Implementation of a base64 encoder, because another one did not immediately
// avail itself.
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2018 Greg Knight <lyngvi@gmail.com>
//
//========================================================================
#ifndef GOO_GBASE64_H
#define GOO_GBASE64_H
#include <string>
#include <vector>
std::string gbase64Encode(const void* input, size_t sz);
inline std::string gbase64Encode(const std::vector<char>& input)
{ return input.empty() ? std::string() : gbase64Encode(&input[0], input.size()); }
inline std::string gbase64Encode(const std::vector<unsigned char>& input)
{ return input.empty() ? std::string() : gbase64Encode(&input[0], input.size()); }
#endif // ndef GOO_GBASE64_H
//========================================================================
//
// gbasename.cc
//
// Wrapper for libgen's basename() call which returns a std::string.
// This is a convenience method working around questionable behavior
// in the copy of basename() provided by libgen.h.
//
// According to man 3 basename:
//
// Both dirname() and basename() may modify the contents of path, so it
// may be desirable to pass a copy when calling one of these functions.
//
// ...
//
// These functions may return pointers to statically allocated memory
// which may be overwritten by subsequent calls. Alternatively, they
// may return a pointer to some part of path, so that the string
// referred to by path should not be modified or freed until the pointer
// returned by the function is no longer required.
//
// Because basename can modify filename (for some reason), we have to
// duplicate our input into a mutable buffer before we can call it.
// The return value might be part of this mutable temporary, but not
// generally the front, so 'char *' cannot be used as our return value.
// The return value might also be a statically allocated string,
// rendering basename (and thus gbasename) non-thread-safe. Because
// we don't know how basename()'s return value is lifecycled, we need
// to duplicate it again into something whose lifecycle we can predict.
//
// This is how a method that should amount to finding the last slash
// in a string ends up requiring two memory allocations while managing
// not to be thread-safe. In a way, it's kind of impressive.
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2018 Greg Knight <lyngvi@gmail.com>
//
//========================================================================
#include "gbasename.h"
#include <libgen.h>
#include <string.h>
std::string gbasename(const char* filename)
{
char* mutabl = strdup(filename);
std::string retu = basename(mutabl);
free(mutabl);
return retu;
}
//========================================================================
//
// gbasename.h
//
// Wrapper for libgen's basename() call which returns a std::string.
// This is a convenience method working around questionable behavior
// in the copy of basename() provided by libgen.h.
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2018 Greg Knight <lyngvi@gmail.com>
//
//========================================================================
#ifndef GBASENAME_H
#define GBASENAME_H
#include <string>
std::string gbasename(const char* input);
#endif // ndef GBASENAME_H
......@@ -15,7 +15,7 @@
//
// Copyright (C) 2006 Scott Turner <scotty1024@mac.com>
// Copyright (C) 2007, 2008 Julien Rebetez <julienr@svn.gnome.org>
// Copyright (C) 2007-2013, 2015-2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2007-2013, 2015-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2007-2013, 2018 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2007, 2008 Iñigo Martínez <inigomartinez@gmail.com>
// Copyright (C) 2007 Jeff Muizelaar <jeff@infidigm.net>
......@@ -1439,8 +1439,8 @@ void Annot::setPage(int pageIndex, bool updateP) {
Object obj1(objNull);
if (pageobj) {
Ref pageRef = pageobj->getRef();
obj1 = Object(pageRef.num, pageRef.gen);
const Ref pageRef = pageobj->getRef();
obj1 = Object(pageRef);
page = pageIndex;
} else {
page = 0;
......@@ -1881,7 +1881,7 @@ void AnnotPopup::initialize(PDFDoc *docA, Dict *dict) {
void AnnotPopup::setParent(Annot *parentA) {
const Ref parentRef = parentA->getRef();
update ("Parent", Object(parentRef.num, parentRef.gen));
update ("Parent", Object(parentRef));
}
void AnnotPopup::setOpen(bool openA) {
......@@ -1994,7 +1994,7 @@ void AnnotMarkup::setPopup(std::unique_ptr<AnnotPopup> &&new_popup) {
if (new_popup) {
const Ref popupRef = new_popup->getRef();
update ("Popup", Object(popupRef.num, popupRef.gen));
update ("Popup", Object(popupRef));
new_popup->setParent(this);
popup = std::move(new_popup);
......@@ -4920,7 +4920,7 @@ void AnnotWidget::updateAppearanceStream()
// Write the AP dictionary
obj1 = Object(new Dict(xref));
obj1.dictAdd("N", Object(updatedAppearanceStream.num, updatedAppearanceStream.gen));
obj1.dictAdd("N", Object(updatedAppearanceStream));
// Update our internal pointers to the appearance dictionary
appearStreams = std::make_unique<AnnotAppearance>(doc, &obj1);
......
......@@ -3,7 +3,7 @@
// FontInfo.cc
//
// Copyright (C) 2005, 2006 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2005-2008, 2010, 2017, 2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2005-2008, 2010, 2017-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
// Copyright (C) 2006 Kouhei Sutou <kou@cozmixng.org>
// Copyright (C) 2009 Pino Toscano <pino@kde.org>
......@@ -192,7 +192,7 @@ FontInfo::FontInfo(GfxFont *font, XRef *xref) {
// look for a ToUnicode map
hasToUnicode = false;
Object fontObj = xref->fetch(fontRef.num, fontRef.gen);
Object fontObj = xref->fetch(fontRef);
if (fontObj.isDict()) {
hasToUnicode = fontObj.dictLookup("ToUnicode").isStream();
}
......
......@@ -112,7 +112,7 @@ void FormWidget::createWidgetAnnotation() {
if (widget)
return;
Object obj1(ref.num, ref.gen);
Object obj1(ref);
widget = new AnnotWidget(doc, &obj, &obj1, field);
}
......
......@@ -14,7 +14,7 @@
// under GPL version 2 or later
//
// Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
// Copyright (C) 2005-2013, 2015-2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2005-2013, 2015-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2006 Thorkild Stray <thorkild@ifi.uio.no>
// Copyright (C) 2006 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2006-2011 Carlos Garcia Campos <carlosgc@gnome.org>
......@@ -505,7 +505,7 @@ Object GfxResources::lookupGState(const char *name) {
return item->copy();
}
auto *item = new Object{xref->fetch(ref.num, ref.gen)};
auto *item = new Object{xref->fetch(ref)};
gStateCache.put(ref, item);
return item->copy();
}
......
......@@ -407,7 +407,7 @@ GfxFontType GfxFont::getFontType(XRef *xref, Dict *fontDict, Ref *embID) {
t = fontUnknownType;
if (embID->num >= 0) {
Object obj3(embID->num, embID->gen);
Object obj3(*embID);
Object obj4 = obj3.fetch(xref);
if (obj4.isStream()) {
obj4.streamReset();
......@@ -603,7 +603,7 @@ GfxFontLoc *GfxFont::locateFont(XRef *xref, PSOutputDev *ps) {
//----- embedded font
if (embFontID.num >= 0) {
embed = true;
Object refObj(embFontID.num, embFontID.gen);
Object refObj(embFontID);
Object embFontObj = refObj.fetch(xref);
if (!embFontObj.isStream()) {
error(errSyntaxError, -1, "Embedded font object is wrong type");
......@@ -819,7 +819,7 @@ char *GfxFont::readEmbFontFile(XRef *xref, int *len) {
char *buf;
Stream *str;
Object obj1(embFontID.num, embFontID.gen);
Object obj1(embFontID);
Object obj2 = obj1.fetch(xref);
if (!obj2.isStream()) {
error(errSyntaxError, -1, "Embedded font file is not a stream");
......
......@@ -13,7 +13,7 @@
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2008, 2010, 2012, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2008, 2010, 2012, 2017, 2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
//
......@@ -89,7 +89,7 @@ Object Object::fetch(XRef *xref, int recursion) const {
CHECK_NOT_DEAD;
return (type == objRef && xref) ?
xref->fetch(ref.num, ref.gen, recursion) : copy();
xref->fetch(ref, recursion) : copy();
}
void Object::free() {
......
......@@ -15,7 +15,7 @@
//
// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
// Copyright (C) 2008 Kees Cook <kees@outflux.net>
// Copyright (C) 2008, 2010, 2017, 2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2008, 2010, 2017-2019 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>
......@@ -172,6 +172,8 @@ public:
{ assert(dictA); type = objDict; dict = dictA; }
explicit Object(Stream *streamA)
{ assert(streamA); type = objStream; stream = streamA; }
explicit Object(const Ref r)
{ type = objRef; ref.num = r.num; ref.gen = r.gen; }
Object(int numA, int genA)
{ type = objRef; ref.num = numA; ref.gen = genA; }
......
......@@ -722,7 +722,7 @@ bool PDFDoc::checkLinearization() {
}
pageRef.gen = xref->getEntry(pageRef.num)->gen;
Object obj = xref->fetch(pageRef.num, pageRef.gen);
Object obj = xref->fetch(pageRef);
if (!obj.isDict("Page")) {
linearizationState = 2;
return false;
......@@ -896,7 +896,7 @@ int PDFDoc::savePageAs(const GooString *name, int pageNo)
getCatalog()->getPage(pageNo)->getMediaBox(),
cropBox);
Ref *refPage = getCatalog()->getPageRef(pageNo);
Object page = getXRef()->fetch(refPage->num, refPage->gen);
Object page = getXRef()->fetch(*refPage);
if (!(f = openFile(name->c_str(), "wb"))) {
error(errIO, -1, "Couldn't open file '{0:t}'", name);
......@@ -1125,7 +1125,7 @@ void PDFDoc::saveIncrementalUpdate (OutStream* outStr)
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);
Object obj1 = xref->fetch(ref, 1 /* recursion */);
Goffset offset = writeObjectHeader(&ref, outStr);
writeObject(&obj1, outStr, fileKey, encAlgorithm, keyLength, ref.num, ref.gen);
writeObjectFooter(outStr);
......@@ -1203,7 +1203,7 @@ void PDFDoc::saveCompleteRewrite (OutStream* outStr)
} else if (type == xrefEntryUncompressed){
ref.num = i;
ref.gen = xref->getEntry(i)->gen;
Object obj1 = xref->fetch(ref.num, ref.gen, 1);
Object obj1 = xref->fetch(ref, 1 /* recursion */);
Goffset offset = writeObjectHeader(&ref, outStr);
// Write unencrypted objects in unencrypted form
if (xref->getEntry(i)->getFlag(XRefEntry::Unencrypted)) {
......@@ -1216,7 +1216,7 @@ void PDFDoc::saveCompleteRewrite (OutStream* outStr)
} else if (type == xrefEntryCompressed) {
ref.num = i;
ref.gen = 0; //compressed entries have gen == 0
Object obj1 = xref->fetch(ref.num, ref.gen, 1);
Object obj1 = xref->fetch(ref, 1 /* recursion */);
Goffset offset = writeObjectHeader(&ref, outStr);
writeObject(&obj1, outStr, fileKey, encAlgorithm, keyLength, ref.num, ref.gen);
writeObjectFooter(outStr);
......@@ -1583,7 +1583,7 @@ Object PDFDoc::createTrailerDict(int uxrefSize, bool incrUpdate, Goffset startxR
trailerDict->set("ID", Object(array));
}
trailerDict->set("Root", Object(root->num, root->gen));
trailerDict->set("Root", Object(*root));
if (incrUpdate) {
trailerDict->set("Prev", Object(startxRef));
......@@ -1730,7 +1730,7 @@ void PDFDoc::markObject (Object* obj, XRef *xRef, XRef *countRef, unsigned int n
if (entry->gen > 9)
break;
}
Object obj1 = getXRef()->fetch(obj->getRef().num, obj->getRef().gen);
Object obj1 = getXRef()->fetch(obj->getRef());
markObject(&obj1, xRef, countRef, numOffset, oldRefNum, newRefNum);
}
break;
......@@ -1744,7 +1744,7 @@ void PDFDoc::replacePageDict(int pageNo, int rotate,
const PDFRectangle *cropBox)
{
Ref *refPage = getCatalog()->getPageRef(pageNo);
Object page = getXRef()->fetch(refPage->num, refPage->gen);
Object page = getXRef()->fetch(*refPage);
Dict *pageDict = page.getDict();
pageDict->remove("MediaBoxssdf");
pageDict->remove("MediaBox");
......@@ -1818,7 +1818,7 @@ bool PDFDoc::markAnnotations(Object *annotsObj, XRef *xRef, XRef *countRef, unsi
} else if (obj2.getRef().num == newPageNum) {
continue;
} else {
Object page = getXRef()->fetch(obj2.getRef().num, obj2.getRef().gen);
Object page = getXRef()->fetch(obj2.getRef());
if (page.isDict()) {
Dict *pageDict = page.getDict();
Object pagetype = pageDict->lookup("Type");
......@@ -2093,7 +2093,7 @@ Page *PDFDoc::parsePage(int page)
}
pageRef.gen = xref->getEntry(pageRef.num)->gen;
Object obj = xref->fetch(pageRef.num, pageRef.gen);
Object obj = xref->fetch(pageRef);
if (!obj.isDict("Page")) {
error(errSyntaxWarning, -1, "Object ({0:d} {1:d}) is not a pageDict", pageRef.num, pageRef.gen);
return nullptr;
......
......@@ -15,7 +15,7 @@
//
// Copyright (C) 2005 Martin Kretzschmar <martink@gnome.org>
// Copyright (C) 2005, 2006 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2006-2009, 2011-2013, 2015-2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2006-2009, 2011-2013, 2015-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2006 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2007, 2008 Brad Hards <bradh@kde.org>
// Copyright (C) 2008, 2009 Koji Otani <sho@bbr.jp>
......@@ -2119,7 +2119,7 @@ void PSOutputDev::setupEmbeddedType1Font(Ref *id, GooString *psName) {
// get the font stream and info
Object obj1, obj2, obj3;
Object refObj(id->num, id->gen);
Object refObj(*id);
Object strObj = refObj.fetch(xref);
if (!strObj.isStream()) {
error(errSyntaxError, -1, "Embedded font file object is not a stream");
......
......@@ -15,7 +15,7 @@
//
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2005 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2005-2013, 2016-2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2005-2013, 2016-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2006-2008 Pino Toscano <pino@kde.org>
// Copyright (C) 2006 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
// Copyright (C) 2006 Scott Turner <scotty1024@mac.com>
......@@ -366,7 +366,7 @@ Annots *Page::getAnnots(XRef *xrefA) {
}
void Page::addAnnot(Annot *annot) {
Ref annotRef = annot->getRef ();
const Ref annotRef = annot->getRef ();
// Make sure we have annots before adding the new one
// even if it's an empty list so that we can safely
......@@ -380,16 +380,16 @@ void Page::addAnnot(Annot *annot) {
// we have to create it
Object obj1 = Object(new Array(xref));
obj1.arrayAdd(Object(annotRef.num, annotRef.gen));
obj1.arrayAdd(Object(annotRef));
annotsRef = xref->addIndirectObject (&obj1);
annotsObj = Object(annotsRef.num, annotsRef.gen);
pageObj.dictSet ("Annots", Object(annotsRef.num, annotsRef.gen));
annotsObj = Object(annotsRef);
pageObj.dictSet ("Annots", Object(annotsRef));
xref->setModifiedObject (&pageObj, pageRef);
} else {
Object obj1 = getAnnotsObject();
if (obj1.isArray()) {
obj1.arrayAdd (Object(annotRef.num, annotRef.gen));
obj1.arrayAdd (Object(annotRef));
if (annotsObj.isRef())
xref->setModifiedObject (&obj1, annotsObj.getRef());
else
......
......@@ -15,7 +15,7 @@
//
// Copyright (C) 2005 Dan Sheridan <dan.sheridan@postman.org.uk>
// Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
// Copyright (C) 2006, 2008, 2010, 2012-2014, 2016-2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2006, 2008, 2010, 2012-2014, 2016-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2007-2008 Julien Rebetez <julienr@svn.gnome.org>
// Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2009, 2010 Ilya Gorenbein <igorenbein@finjan.com>
......@@ -1072,6 +1072,11 @@ Object XRef::getCatalog() {
return catalog;
}
Object XRef::fetch(const Ref ref, int recursion)
{
return fetch(ref.num, ref.gen, recursion);
}
Object XRef::fetch(int num, int gen, int recursion) {
XRefEntry *e;
Parser *parser;
......@@ -1206,7 +1211,7 @@ Object XRef::createDocInfoIfNoneExists() {
obj = Object(new Dict(this));
const Ref ref = addIndirectObject(&obj);
trailerDict.dictSet("Info", Object(ref.num, ref.gen));
trailerDict.dictSet("Info", Object(ref));
return obj;
}
......@@ -1635,12 +1640,12 @@ void XRef::markUnencrypted(Object *obj) {
}
case objRef:
{
Ref ref = obj->getRef();
const Ref ref = obj->getRef();
XRefEntry *e = getEntry(ref.num);
if (e->getFlag(XRefEntry::Unencrypted))
return; // We've already been here: prevent infinite recursion
e->setFlag(XRefEntry::Unencrypted, true);
obj1 = fetch(ref.num, ref.gen);
obj1 = fetch(ref);
markUnencrypted(&obj1);
break;
}
......
......@@ -14,7 +14,7 @@
// under GPL version 2 or later
//
// Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
// Copyright (C) 2006, 2008, 2010-2013, 2017, 2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2006, 2008, 2010-2013, 2017-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2007-2008 Julien Rebetez <julienr@svn.gnome.org>
// Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2010 Ilya Gorenbein <igorenbein@finjan.com>
......@@ -143,6 +143,7 @@ public:
Object getCatalog();
// Fetch an indirect reference.
Object fetch(const Ref ref, int recursion = 0);
Object fetch(int num, int gen, int recursion = 0);
// Return the document's Info dictionary (if any).
......
/* poppler-document.cc: qt interface to poppler
* Copyright (C) 2005, Net Integration Technologies, Inc.
* Copyright (C) 2005, 2008, Brad Hards <bradh@frogmouth.net>
* Copyright (C) 2005-2010, 2012, 2013, 2015, 2017, 2018, Albert Astals Cid <aacid@kde.org>
* Copyright (C) 2005-2010, 2012, 2013, 2015, 2017-2019, Albert Astals Cid <aacid@kde.org>
* Copyright (C) 2006-2010, Pino Toscano <pino@kde.org>
* Copyright (C) 2010, 2011 Hib Eris <hib@hiberis.nl>
* Copyright (C) 2012 Koji Otani <sho@bbr.jp>
......@@ -246,7 +246,7 @@ namespace Poppler {
{
XRef *xref = m_doc->doc->getXRef()->copy();
Object refObj(fi.m_data->embRef.num, fi.m_data->embRef.gen);
Object refObj(fi.m_data->embRef);
Object strObj = refObj.fetch(xref);
if (strObj.isStream())
{
......
......@@ -121,6 +121,7 @@ install(FILES pdftotext.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
# pdftohtml
set(pdftohtml_SOURCES ${common_srcs}
InMemoryFile.cc
pdftohtml.cc
HtmlFonts.cc
HtmlLinks.cc
......
This diff is collapsed.
......@@ -36,6 +36,7 @@
#include <stdio.h>
#include "goo/GooList.h"
#include "goo/gbasename.h"
#include "GfxFont.h"
#include "OutputDev.h"
#include "HtmlLinks.h"
......@@ -44,13 +45,6 @@
#include "Catalog.h"
#include "UnicodeMap.h"
#ifdef _WIN32
# define SLASH '\\'
#else
# define SLASH '/'
#endif
#define xoutRound(x) ((int)(x + 0.5))
#define DOCTYPE "<!DOCTYPE html>"
......@@ -70,7 +64,6 @@ enum UnicodeTextDirection {
textDirTopBottom
};
class HtmlString {
public:
......@@ -123,7 +116,7 @@ class HtmlPage {
public:
// Constructor.
HtmlPage(bool rawOrder, const char *imgExtVal);
HtmlPage(bool rawOrder);
// Destructor.
~HtmlPage();
......@@ -166,7 +159,7 @@ public:
// number of images on the current page
int getNumImages() { return imgList->getLength(); }
void dump(FILE *f, int pageNum);
void dump(FILE *f, int pageNum, const std::vector<std::string>& backgroundImages);
// Clear the page.
void clear();
......@@ -186,7 +179,7 @@ private:
void setDocName(const char* fname);
void dumpAsXML(FILE* f,int page);
void dumpComplex(FILE* f, int page);
void dumpComplex(FILE* f, int page, const std::vector<std::string>& backgroundImages);
int dumpComplexHeaders(FILE * const file, FILE *& pageFile, int page);
// marks the position of the fonts that belong to current page (for noframes)
......@@ -196,7 +189,6 @@ private:
GooList *imgList;
GooString *DocName;
GooString *imgExt;
int pageWidth;
int pageHeight;
int firstPage; // used to begin the numeration of pages
......@@ -241,7 +233,6 @@ public:
const char *keywords,
const char *subject,
const char *date,
const char *extension,
bool rawOrder,
int firstPage = 1,
bool outline = 0);
......@@ -290,6 +281,10 @@ public:
// End a page.
void endPage() override;
// add a background image to the list of background images,
// as this seems to be done outside other processing. takes ownership of img.
void addBackgroundImage(const std::string& img);
//----- update text state
void updateFont(GfxState *state) override;
......@@ -352,6 +347,7 @@ private:
GooList *glMetaVars;
Catalog *catalog;
Page *docPage;
std::vector<std::string> backgroundImages;
friend class HtmlPage;
};
......
//========================================================================
//
// InMemoryFile.cc
//
// Represents a file in-memory with GNU's stdio wrappers.
// NOTE as of this writing, open() depends on the glibc 'fopencookie'
// extension and is not supported on other platforms. The
// HAVE_IN_MEMORY_FILE macro is intended to reflect whether this class is
// usable.
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2018 Greg Knight <lyngvi@gmail.com>
//
//========================================================================
#include "InMemoryFile.h"
#include <string.h>
#include <sstream>
InMemoryFile::InMemoryFile()
: iohead(0)
, fptr(nullptr)
{
}
ssize_t InMemoryFile::_read(char* buf, size_t sz)
{
auto toRead = std::min<size_t>(data.size() - iohead, sz);
memcpy(&buf[0], &data[iohead], toRead);
iohead += toRead;
return toRead;
}
ssize_t InMemoryFile::_write(const char* buf, size_t sz)
{
if (iohead + sz > data.size())
data.resize(iohead + sz);
memcpy(&data[iohead], buf, sz);
iohead += sz;
return sz;
}
int InMemoryFile::_seek(off64_t* offset, int whence)
{
switch (whence) {
case SEEK_SET: iohead = (*offset); break;
case SEEK_CUR: iohead += (*offset); break;
case SEEK_END: iohead -= (*offset); break;
}
(*offset) = std::min<off64_t>(std::max<off64_t>(iohead, 0l), data.size());
iohead = static_cast<size_t>(*offset);
return 0;
}
FILE* InMemoryFile::open(const char* mode)
{
#if HAVE_IN_MEMORY_FILE_FOPENCOOKIE
if (fptr != nullptr) {
fprintf(stderr, "InMemoryFile: BUG: Why is this opened more than once?");
return nullptr; // maybe there's some legit reason for it, whoever comes up with one can remove this line
}
static cookie_io_functions_t methods = {
/* .read = */ [](void* self, char* buf, size_t sz) { return ((InMemoryFile*)self)->_read(buf, sz); },
/* .write = */ [](void* self, const char* buf, size_t sz) { return ((InMemoryFile*)self)->_write(buf, sz); },
/* .seek = */ [](void* self, off64_t* offset, int whence) { return ((InMemoryFile*)self)->_seek(offset, whence); },
/* .close = */ [](void* self) { ((InMemoryFile*)self)->fptr = nullptr; return 0; },
};
return fptr = fopencookie(this, mode, methods);
#else
fprintf (stderr, "If you can read this, your platform does not support the features necessary to achieve your goals.");
return nullptr;
#endif
}
//========================================================================
//
// InMemoryFile.h
//
// Represents a file in-memory with GNU's stdio wrappers.
// NOTE as of this writing, open() depends on the glibc 'fopencookie'
// extension and is not supported on other platforms. The
// HAVE_IN_MEMORY_FILE macro is intended to reflect whether this class is
// usable.
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2018 Greg Knight <lyngvi@gmail.com>
//
//========================================================================
#ifndef IN_MEMORY_FILE_H
#define IN_MEMORY_FILE_H
#include <stdio.h>
#include <string>
#include <vector>
#if defined(__USE_GNU) && !defined(__ANDROID_API__)
# define HAVE_IN_MEMORY_FILE (1)
# define HAVE_IN_MEMORY_FILE_FOPENCOOKIE (1) // used internally
#endif
class InMemoryFile {
private:
size_t iohead;
std::vector<char> data;
FILE *fptr;
ssize_t _read(char* buf, size_t sz);
ssize_t _write(const char* buf, size_t sz);
int _seek(off64_t* offset, int whence);
public:
InMemoryFile();
public:
/* Returns a file handle for this file. This is scoped to this object
* and must be fclosed() by the caller before destruction. */
FILE* open(const char* mode);
const std::vector<char>& getBuffer() const
{ return data; }
};
#endif // IN_MEMORY_FILE_H
......@@ -24,10 +24,10 @@
#include <time.h>
#include <hasht.h>
#include <fstream>
#include <libgen.h>
#include "parseargs.h"
#include "Object.h"
#include "Array.h"
#include "goo/gbasename.h"
#include "Page.h"
#include "PDFDoc.h"
#include "PDFDocFactory.h"
......@@ -108,9 +108,7 @@ static void dumpSignature(int sig_num, int sigCount, FormWidgetSignature *sig_wi
// since { is the magic character to replace things we need to put it twice where
// we don't want it to be replaced
GooString *format = GooString::format("{{0:s}}.sig{{1:{0:d}d}}", sigCountLength);
char *filenameCopy = strdup(filename);
GooString *path = GooString::format(format->c_str(), basename(filenameCopy), sig_num);
free(filenameCopy);
GooString *path = GooString::format(format->c_str(), gbasename(filename).c_str(), sig_num);
printf("Signature #%d (%u bytes) => %s\n", sig_num, signature->getLength(), path->c_str());
std::ofstream outfile(path->c_str(), std::ofstream::binary);
outfile.write(signature->c_str(), signature->getLength());
......
......@@ -43,6 +43,9 @@ generate complex output
.B \-s
generate single HTML that includes all pages
.TP
.B \-dataurls
use data URLs instead of external images in HTML. No available in all platforms
.TP
.B \-i
ignore images
.TP
......
......@@ -46,6 +46,8 @@
#include <time.h>
#include "parseargs.h"
#include "goo/GooString.h"
#include "goo/gbase64.h"
#include "goo/gbasename.h"
#include "goo/gmem.h"
#include "Object.h"
#include "Stream.h"
......@@ -68,6 +70,7 @@
#include "DateInfo.h"
#include "goo/gfile.h"
#include "Win32Console.h"
#include "InMemoryFile.h"
static int firstPage = 1;
static int lastPage = 0;
......@@ -77,6 +80,7 @@ static bool printHelp = false;
bool printHtml = false;
bool complexMode=false;
bool singleHtml=false; // singleHtml
bool dataUrls = false;
bool ignore=false;
static char extension[5]="png";
static double scale=1.5;
......@@ -123,6 +127,10 @@ static const ArgDesc argDesc[] = {
"generate complex document"},
{"-s", argFlag, &singleHtml, 0,
"generate single document that includes all pages"},
#ifdef HAVE_IN_MEMORY_FILE
{"-dataurls", argFlag, &dataUrls, 0,
"use data URLs instead of external images in HTML"},
#endif
{"-i", argFlag, &ignore, 0,
"ignore images"},
{"-noframes", argFlag, &noframes, 0,
......@@ -310,7 +318,7 @@ int main(int argc, char *argv[]) {
if (scale>3.0) scale=3.0;
if (scale<0.5) scale=0.5;
if (complexMode || singleHtml) {
if (complexMode) {
//noframes=false;
stout=false;
}
......@@ -318,7 +326,6 @@ int main(int argc, char *argv[]) {
if (stout) {
noframes=true;
complexMode=false;
singleHtml=false;
}
if (xml)
......@@ -366,7 +373,6 @@ int main(int argc, char *argv[]) {
keywords ? keywords->c_str() : nullptr,
subject ? subject->c_str() : nullptr,
date ? date->c_str() : nullptr,
extension,
rawOrder,
firstPage,
doOutline);
......@@ -387,13 +393,6 @@ int main(int argc, char *argv[]) {
{
delete date;
}
if (htmlOut->isOk())
{
doc->displayPages(htmlOut, firstPage, lastPage, 72 * scale, 72 * scale, 0,
true, false, false);
htmlOut->dumpDocOutline(doc);
}
if ((complexMode || singleHtml) && !xml && !ignore) {
#ifdef HAVE_SPLASH
......@@ -409,6 +408,7 @@ int main(int argc, char *argv[]) {
splashOut->startDoc(doc);
for (int pg = firstPage; pg <= lastPage; ++pg) {
InMemoryFile imf;
doc->displayPage(splashOut, pg,
72 * scale, 72 * scale,
0, true, false, false);
......@@ -416,10 +416,22 @@ int main(int argc, char *argv[]) {
imgFileName = GooString::format("{0:s}{1:03d}.{2:s}",
htmlFileName->c_str(), pg, extension);
bitmap->writeImgFile(format, imgFileName->c_str(),
72 * scale, 72 * scale);
auto f1 = dataUrls ? imf.open("wb") : fopen(imgFileName->c_str(), "wb");
if (!f1) {
fprintf(stderr, "Could not open %s\n", imgFileName->c_str());
delete imgFileName;
continue;
}
bitmap->writeImgFile(format, f1, 72 * scale, 72 * scale);
fclose(f1);
if (dataUrls) {
htmlOut->addBackgroundImage(
std::string((format == splashFormatJpeg) ? "data:image/jpeg;base64," : "data:image/png;base64,") +
gbase64Encode(imf.getBuffer())
);
} else {
htmlOut->addBackgroundImage(gbasename(imgFileName->c_str()));
}
delete imgFileName;
}
......@@ -434,7 +446,14 @@ int main(int argc, char *argv[]) {
return -1;
#endif
}
if (htmlOut->isOk())
{
doc->displayPages(htmlOut, firstPage, lastPage, 72 * scale, 72 * scale, 0,
true, false, false);
htmlOut->dumpDocOutline(doc);
}
delete htmlOut;
exit_status = EXIT_SUCCESS;
......
......@@ -7,7 +7,7 @@
// Copyright (C) 2011-2015, 2017 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2012 Arseny Solokha <asolokha@gmx.com>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2012, 2014, 2017, 2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2012, 2014, 2017-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2013 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2015 Arthur Stavisky <vovodroid@gmail.com>
......@@ -68,7 +68,7 @@ static void doMergeNameTree(PDFDoc *doc, XRef *srcXRef, XRef *countRef, int oldR
}
}
newNameArray->add(Object(new GooString(key.getString()->c_str())));
newNameArray->add(Object(value.getRef().num, value.getRef().gen));
newNameArray->add(Object(value.getRef()));
}
}
while (j < mergeNameArray.arrayGetLength() - 1) {
......@@ -287,7 +287,7 @@ int main (int argc, char *argv[])
docs[i]->getCatalog()->getPage(j)->getRotate(),
docs[i]->getCatalog()->getPage(j)->getMediaBox(), cropBox);
Ref *refPage = docs[i]->getCatalog()->getPageRef(j);
Object page = docs[i]->getXRef()->fetch(refPage->num, refPage->gen);
Object page = docs[i]->getXRef()->fetch(*refPage);
Dict *pageDict = page.getDict();
Object *resDict = docs[i]->getCatalog()->getPage(j)->getResourceDictObject();
if (resDict->isDict()) {
......