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

Reply via email to