[poppler] poppler/PDFDoc.cc utils/pdfunite.cc
Albert Astals Cid
aacid at kemper.freedesktop.org
Thu Aug 27 14:02:32 PDT 2015
poppler/PDFDoc.cc | 1
utils/pdfunite.cc | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 154 insertions(+), 3 deletions(-)
New commits:
commit 3e19bec738889ee9140379ac3f871552dbb9bf41
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date: Thu Aug 27 23:01:21 2015 +0200
pdfunite: Insert embedded files in result pdf
Bug #90066
diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
index e99af26..46c4544 100644
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@ -1561,7 +1561,6 @@ void PDFDoc::replacePageDict(int pageNo, int rotate,
void PDFDoc::markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum)
{
- pageDict->remove("Names");
pageDict->remove("OpenAction");
pageDict->remove("Outlines");
pageDict->remove("StructTreeRoot");
diff --git a/utils/pdfunite.cc b/utils/pdfunite.cc
index b35090c..170355d 100644
--- a/utils/pdfunite.cc
+++ b/utils/pdfunite.cc
@@ -4,7 +4,7 @@
//
// This file is licensed under the GPLv2 or later
//
-// Copyright (C) 2011-2014 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2011-2015 Thomas Freitag <Thomas.Freitag at alfa.de>
// Copyright (C) 2012 Arseny Solokha <asolokha at gmx.com>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso at hotmail.it>
// Copyright (C) 2012, 2014 Albert Astals Cid <aacid at kde.org>
@@ -37,6 +37,132 @@ static const ArgDesc argDesc[] = {
{NULL}
};
+void doMergeNameTree(PDFDoc *doc, XRef *srcXRef, XRef *countRef, int oldRefNum, int newRefNum, Dict *srcNameTree, Dict *mergeNameTree, int numOffset) {
+ Object mergeNameArray;
+ Object srcNameArray;
+ mergeNameTree->lookup("Names", &mergeNameArray);
+ srcNameTree->lookup("Names", &srcNameArray);
+ if (mergeNameArray.isArray() && srcNameArray.isArray()) {
+ Object *newNameArray = new Object();
+ newNameArray->initArray(srcXRef);
+ int j = 0;
+ for (int i = 0; i < srcNameArray.arrayGetLength() - 1; i += 2) {
+ Object key;
+ Object value;
+ srcNameArray.arrayGetNF(i, &key);
+ srcNameArray.arrayGetNF(i + 1, &value);
+ if (key.isString() && value.isRef()) {
+ while (j < mergeNameArray.arrayGetLength() - 1) {
+ Object mkey;
+ Object mvalue;
+ mergeNameArray.arrayGetNF(j, &mkey);
+ mergeNameArray.arrayGetNF(j + 1, &mvalue);
+ if (mkey.isString() && mvalue.isRef()) {
+ if (mkey.getString()->cmp(key.getString()) < 0) {
+ Object *newKey = new Object();
+ newKey->initString(new GooString(mkey.getString()->getCString()));
+ newNameArray->arrayAdd(newKey);
+ Object *newValue = new Object();
+ newValue->initRef(mvalue.getRef().num + numOffset, mvalue.getRef().gen);
+ newNameArray->arrayAdd(newValue);
+ delete newKey;
+ delete newValue;
+ j += 2;
+ } else if (mkey.getString()->cmp(key.getString()) == 0) {
+ j += 2;
+ } else {
+ mkey.free();
+ mvalue.free();
+ break;
+ }
+ } else {
+ j += 2;
+ }
+ mkey.free();
+ mvalue.free();
+ }
+ Object *newKey = new Object();
+ newKey->initString(new GooString(key.getString()->getCString()));
+ newNameArray->arrayAdd(newKey);
+ Object *newValue = new Object();
+ newValue->initRef(value.getRef().num, value.getRef().gen);
+ newNameArray->arrayAdd(newValue);
+ delete newKey;
+ delete newValue;
+ }
+ key.free();
+ value.free();
+ }
+ while (j < mergeNameArray.arrayGetLength() - 1) {
+ Object mkey;
+ Object mvalue;
+ mergeNameArray.arrayGetNF(j, &mkey);
+ mergeNameArray.arrayGetNF(j + 1, &mvalue);
+ if (mkey.isString() && mvalue.isRef()) {
+ Object *newKey = new Object();
+ newKey->initString(new GooString(mkey.getString()->getCString()));
+ newNameArray->arrayAdd(newKey);
+ Object *newValue = new Object();
+ newValue->initRef(mvalue.getRef().num + numOffset, mvalue.getRef().gen);
+ newNameArray->arrayAdd(newValue);
+ delete newKey;
+ delete newValue;
+ }
+ j += 2;
+ mkey.free();
+ mvalue.free();
+ }
+ srcNameTree->set("Names", newNameArray);
+ doc->markPageObjects(mergeNameTree, srcXRef, countRef, numOffset, oldRefNum, newRefNum);
+ delete newNameArray;
+ } else if (srcNameArray.isNull() && mergeNameArray.isArray()) {
+ Object *newNameArray = new Object();
+ newNameArray->initArray(srcXRef);
+ for (int i = 0; i < mergeNameArray.arrayGetLength() - 1; i += 2) {
+ Object key;
+ Object value;
+ mergeNameArray.arrayGetNF(i, &key);
+ mergeNameArray.arrayGetNF(i + 1, &value);
+ if (key.isString() && value.isRef()) {
+ Object *newKey = new Object();
+ newKey->initString(new GooString(key.getString()->getCString()));
+ newNameArray->arrayAdd(newKey);
+ Object *newValue = new Object();
+ newValue->initRef(value.getRef().num + numOffset, value.getRef().gen);
+ newNameArray->arrayAdd(newValue);
+ delete newKey;
+ delete newValue;
+ }
+ key.free();
+ value.free();
+ }
+ srcNameTree->add(copyString("Names"), newNameArray);
+ doc->markPageObjects(mergeNameTree, srcXRef, countRef, numOffset, oldRefNum, newRefNum);
+ }
+ mergeNameArray.free();
+ srcNameArray.free();
+}
+
+void doMergeNameDict(PDFDoc *doc, XRef *srcXRef, XRef *countRef, int oldRefNum, int newRefNum, Dict *srcNameDict, Dict *mergeNameDict, int numOffset) {
+ for (int i = 0; i < mergeNameDict->getLength(); i++) {
+ const char *key = mergeNameDict->getKey(i);
+ Object mergeNameTree;
+ Object srcNameTree;
+ mergeNameDict->lookup(key, &mergeNameTree);
+ srcNameDict->lookup(key, &srcNameTree);
+ if (srcNameTree.isDict() && mergeNameTree.isDict()) {
+ doMergeNameTree(doc, srcXRef, countRef, oldRefNum, newRefNum, srcNameTree.getDict(), mergeNameTree.getDict(), numOffset);
+ } else if (srcNameTree.isNull() && mergeNameTree.isDict()) {
+ Object *newNameTree = new Object();
+ newNameTree->initDict(srcXRef);
+ doMergeNameTree(doc, srcXRef, countRef, oldRefNum, newRefNum, newNameTree->getDict(), mergeNameTree.getDict(), numOffset);
+ srcNameDict->add(copyString(key), newNameTree);
+ }
+ srcNameTree.free();
+ mergeNameTree.free();
+ }
+}
+
///////////////////////////////////////////////////////////////////////////
int main (int argc, char *argv[])
///////////////////////////////////////////////////////////////////////////
@@ -109,10 +235,11 @@ int main (int argc, char *argv[])
yRef->add(0, 65535, 0, gFalse);
PDFDoc::writeHeader(outStr, majorVersion, minorVersion);
- // handle OutputIntents, AcroForm & OCProperties
+ // handle OutputIntents, AcroForm, OCProperties & Names
Object intents;
Object afObj;
Object ocObj;
+ Object names;
if (docs.size() >= 1) {
Object catObj;
docs[0]->getXRef()->getCatalog(&catObj);
@@ -127,6 +254,10 @@ int main (int argc, char *argv[])
if (!ocObj.isNull() && ocObj.isDict()) {
docs[0]->markPageObjects(ocObj.getDict(), yRef, countRef, 0, refPage->num, refPage->num);
}
+ catDict->lookup("Names", &names);
+ if (!names.isNull() && names.isDict()) {
+ docs[0]->markPageObjects(names.getDict(), yRef, countRef, 0, refPage->num, refPage->num);
+ }
if (intents.isArray() && intents.arrayGetLength() > 0) {
for (i = 1; i < (int) docs.size(); i++) {
Object pagecatObj, pageintents;
@@ -216,6 +347,7 @@ int main (int argc, char *argv[])
Object *newResource = new Object();
newResource->initDict(resDict);
pageDict->set("Resources", newResource);
+ delete newResource;
}
pages.push_back(page);
offsets.push_back(numOffset);
@@ -227,6 +359,19 @@ int main (int argc, char *argv[])
annotsObj.free();
}
}
+ Object pageCatObj, pageNames;
+ docs[i]->getXRef()->getCatalog(&pageCatObj);
+ Dict *pageCatDict = pageCatObj.getDict();
+ pageCatDict->lookup("Names", &pageNames);
+ if (!pageNames.isNull() && pageNames.isDict()) {
+ if (!names.isDict()) {
+ names.free();
+ names.initDict(yRef);
+ }
+ doMergeNameDict(docs[i], yRef, countRef, 0, 0, names.getDict(), pageNames.getDict(), numOffset);
+ }
+ pageNames.free();
+ pageCatObj.free();
objectsCount += docs[i]->writePageObjects(outStr, yRef, numOffset, gTrue);
numOffset = yRef->getNumObjects() + 1;
}
@@ -261,6 +406,12 @@ int main (int argc, char *argv[])
PDFDoc::writeObject(&ocObj, outStr, yRef, 0, NULL, cryptRC4, 0, 0, 0);
ocObj.free();
}
+ // insert Names
+ if (!names.isNull() && names.isDict()) {
+ outStr->printf(" /Names ");
+ PDFDoc::writeObject(&names, outStr, yRef, 0, NULL, cryptRC4, 0, 0, 0);
+ names.free();
+ }
outStr->printf(">>\nendobj\n");
objectsCount++;
@@ -305,6 +456,7 @@ int main (int argc, char *argv[])
delete trailerDict;
outStr->close();
+ delete outStr;
fclose(f);
delete yRef;
delete countRef;
More information about the poppler
mailing list