Hi,
First of all thank you all for giving me suggestions & comments. I made
changes to the previous patch and attached the new patch for getting/setting
PDF ID.
I attached the patch without having the API Documentation. I will do it as
early as possible. I think I made indentation correctly this time. Mean
while, send me suggestions/comments about this patch.
If possible tell me how to add API documentation.
@Carlos Garcia : I also thought that PDFDoc::SaveAS() will set the ID in the
document. But that is not always.
In PDFDoc::saveAs(GooString *filename,PDFWriteMode mode). We have to pass
the mode as writeForceRewrite then only it generates the ID and set it. But
I tried with some PDF files, It is setting the ID in the trailer dictionary,
but it is loosing the data. I don't know why it is happening. It has
happened for all pdf files I have checked so far.
Thanks
--
A srinivas
Sorry If you receive multiple copies of the mail
Index: poppler-0.14.0/poppler/PDFDoc.h
===================================================================
--- poppler-0.14.0/poppler/PDFDoc.h (revision 204)
+++ poppler-0.14.0/poppler/PDFDoc.h (working copy)
@@ -206,6 +206,11 @@
int getPDFMajorVersion() { return pdfMajorVersion; }
int getPDFMinorVersion() { return pdfMinorVersion; }
+ // Return the PDF ID contains in the trailer dictionary
+ GBool getID(GooString *permanent_id, GooString *update_id);
+ // Set the PDF ID in the trailer dictionary
+ GBool setID();
+
// Save this file with another name.
int saveAs(GooString *name, PDFWriteMode mode=writeStandard);
// Save this file in the given output stream.
Index: poppler-0.14.0/poppler/PDFDoc.cc
===================================================================
--- poppler-0.14.0/poppler/PDFDoc.cc (revision 204)
+++ poppler-0.14.0/poppler/PDFDoc.cc (working copy)
@@ -445,6 +445,133 @@
return lin;
}
+static void
+get_id(char* encodedid,char *pdfid) {
+ 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);
+}
+
+GBool PDFDoc::getID(GooString *permanent_id,GooString *update_id) {
+
+ Object obj;
+ xref->getTrailerDict()->dictLookup("ID", &obj);
+
+ if (obj.isNull())
+ {
+ obj.free();
+ return NULL;
+ }
+
+ Object val1,val2;
+ obj.arrayGet(0,&val1);
+ obj.arrayGet(1,&val2);
+ obj.free();
+
+ char tmpid[33];
+ get_id(val1.getString()->getCString(),tmpid);
+ permanent_id->append(tmpid,32);
+ get_id(val2.getString()->getCString(),tmpid);
+ update_id->append(tmpid,32);
+
+ val1.free();
+ val2.free();
+ return true;
+}
+
+GBool PDFDoc::setID() {
+ GooString permanent_id,update_id;
+
+ if (getID(&permanent_id,&update_id)) {
+ return false;
+ } else {
+ GooString message;
+ char buffer[64];
+ sprintf(buffer, "%i", (int)time(NULL));
+ message.append(buffer);
+
+ char *filename;
+ if(getFileName() != NULL) {
+ filename = getFileName()->getCString();
+ message.append(basename(filename));
+ } else { //non-files just append the dummy filename to the message
+ filename = "streamwithoutfilename.pdf";
+ message.append(filename);
+ }
+
+ // file size
+ unsigned int fileSize = 0;
+
+ FILE *f;
+ if (!(f = fopen(filename,"r"))) { //non-file find size from the stream
+ BaseStream *str = getBaseStream();
+ int c;
+ str->reset();
+ while ((c = str->getChar()) != EOF) {
+ fileSize++;
+ }
+ str->close();
+ } else {
+ fseek(f,0,SEEK_END);
+ fileSize = ftell(f);
+ fclose(f);
+ }
+ sprintf(buffer, "%i", fileSize);
+ message.append(buffer);
+
+ Object obj1;
+
+ //info dict -- only use text string
+ if (xref->getDocInfo(&obj1)->isDict()) {
+ for(int i=0; i<obj1.getDict()->getLength(); i++) {
+ Object obj2;
+ obj1.getDict()->getVal(i, &obj2);
+ if (obj2.isString()) {
+ message.append(obj2.getString());
+ }
+ obj2.free();
+ }
+ }
+ obj1.free();
+
+ Guchar digest[16];
+ Decrypt::md5((Guchar*)message.getCString(), message.getLength(), digest);
+
+ Object obj2,obj3;
+
+ obj2.initString(new GooString((const char*)digest,16));
+ obj3.initString(new GooString((const char*)digest,16));
+
+ Object *trailerDict = xref->getTrailerDict();
+ //create ID array
+ obj1.initArray(xref);
+
+ obj1.arrayAdd(&obj2);
+ obj1.arrayAdd(&obj3);
+
+ trailerDict->dictSet("ID", &obj1);
+
+ OutStream *outStr;
+
+ // if PDFDoc was created from the file update the file content with the above changes.
+ if ((f = fopen(filename,"r+"))) {
+ outStr = new FileOutStream(f,0);
+ saveAs(outStr,writeForceIncremental);
+ fclose(f);
+ delete outStr;
+ obj1.free();
+ obj2.free();
+ obj3.free();
+ }
+ return true;
+ }
+}
+
int PDFDoc::saveAs(GooString *name, PDFWriteMode mode) {
FILE *f;
OutStream *outStr;
Index: poppler-0.14.0/glib/poppler-document.cc
===================================================================
--- poppler-0.14.0/glib/poppler-document.cc (revision 204)
+++ poppler-0.14.0/glib/poppler-document.cc (working copy)
@@ -55,6 +55,8 @@
PROP_VIEWER_PREFERENCES,
PROP_PERMISSIONS,
PROP_METADATA
+ PROP_PERMANENT_ID,
+ PROP_UPDATE_ID
};
static void poppler_document_layers_free (PopplerDocument *document);
@@ -762,6 +764,25 @@
}
}
break;
+ case PROP_PERMANENT_ID:
+ {
+ GooString permanent_id,update_id;
+ if(document->doc->getID(&permanent_id,&update_id))
+ {
+ g_value_set_string(value,permanent_id.getCString());
+ }
+ break;
+ }
+ case PROP_UPDATE_ID:
+ {
+ GooString permanent_id,update_id;
+ if(document->doc->getID(&permanent_id,&update_id))
+ {
+ g_value_set_string(value,update_id.getCString());
+ }
+ break;
+ }
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -931,6 +952,23 @@
"Embedded XML metadata",
NULL,
G_PARAM_READABLE));
+ g_object_class_install_property
+ (G_OBJECT_CLASS (klass),
+ PROP_PERMANENT_ID,
+ g_param_spec_string ("permanent-id",
+ "Permanent Id",
+ "Permanent Id of the PDF Document",
+ NULL,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property
+ (G_OBJECT_CLASS (klass),
+ PROP_UPDATE_ID,
+ g_param_spec_string ("update-id",
+ "Update Id",
+ "Update Id of the PDF Document",
+ NULL,
+ G_PARAM_READABLE));
}
static void
@@ -1948,3 +1986,24 @@
return retval;
}
+
+gboolean
+poppler_document_get_id (PopplerDocument *document,PopplerDocumentId *documentid)
+{
+ GooString permanent_id,update_id;
+
+ if (document->doc->getID(&permanent_id,&update_id)) {
+ g_stpcpy(documentid->permanent_id,permanent_id.getCString());
+ g_stpcpy(documentid->update_id,update_id.getCString());
+
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+gboolean
+poppler_document_set_id (PopplerDocument *document)
+{
+ return document->doc->setID() ? TRUE : FALSE;
+}
Index: poppler-0.14.0/glib/poppler-document.h
===================================================================
--- poppler-0.14.0/glib/poppler-document.h (revision 204)
+++ poppler-0.14.0/glib/poppler-document.h (working copy)
@@ -89,7 +89,12 @@
} PopplerPermissions;
+typedef struct _PopplerDocumentId
+{
+ gchar permanent_id[33];
+ gchar update_id[33];
+}PopplerDocumentId;
GType poppler_document_get_type (void) G_GNUC_CONST;
PopplerDocument *poppler_document_new_from_file (const char *uri,
@@ -122,6 +127,13 @@
PopplerFormField *poppler_document_get_form_field (PopplerDocument *document,
gint id);
+/*Get the PDF IDs from the trailer dictionary.
+Pdf Ids contains two strings of length 16 bytes each, represented in Hex*/
+gboolean poppler_document_get_id(PopplerDocument *document,PopplerDocumentId *documentid);
+
+/* Generate the Pdf Id and set it in the Pdf file*/
+gboolean poppler_document_set_id (PopplerDocument *document);
+
/* Interface for getting the Index of a poppler_document */
#define POPPLER_TYPE_INDEX_ITER (poppler_index_iter_get_type ())
GType poppler_index_iter_get_type (void) G_GNUC_CONST;
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler