Index: poppler-0.14.0/poppler/PDFDoc.h =================================================================== --- poppler-0.14.0/poppler/PDFDoc.h (revision 3) +++ poppler-0.14.0/poppler/PDFDoc.h (working copy) @@ -206,6 +206,9 @@ int getPDFMajorVersion() { return pdfMajorVersion; } int getPDFMinorVersion() { return pdfMinorVersion; } + //Return the PDF ID in the trailer dictionary (if any). + GBool getID(GooString *permanent_id, GooString *update_id); + // 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 3) +++ poppler-0.14.0/poppler/PDFDoc.cc (working copy) @@ -70,6 +70,7 @@ #define headerSearchSize 1024 // read this many bytes at beginning of // file to look for '%PDF' +#define pdfIdLength 32 // PDF Document IDs (PermanentId, UpdateId) length //------------------------------------------------------------------------ // PDFDoc @@ -445,6 +446,58 @@ return lin; } +static bool +get_id(Object val, GooString *id) { + char pdfid[pdfIdLength+1]; + if (val.isString()) { + GooString *temp; + temp = val.getString(); + if (temp->getLength() != 16) { // security check + return false; + } else { + char *encodedid = temp->getCString(); + 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); + id->Set (pdfid, pdfIdLength); + } + } else { + return false; + } + return true; +} + +GBool PDFDoc::getID(GooString *permanent_id, GooString *update_id) { + Object obj; + xref->getTrailerDict()->dictLookup ("ID", &obj); + + if (!obj.isArray()) + { + obj.free(); + return false; + } else if (obj.arrayGetLength() != 2) { // security check + return false; + } + + Object val1, val2; + obj.arrayGet(0, &val1); + obj.arrayGet(1, &val2); + + obj.free(); + + if (!permanent_id && !update_id) {// security check + return false; + } else { + bool pid, uid; + pid = get_id (val1, permanent_id); + uid = get_id (val2, update_id); + if (!pid && !uid) + return false; + } + + val1.free(); + val2.free(); + return true; +} + int PDFDoc::saveAs(GooString *name, PDFWriteMode mode) { FILE *f; OutStream *outStr; Index: poppler-0.14.0/glib/poppler.h =================================================================== --- poppler-0.14.0/glib/poppler.h (revision 3) +++ poppler-0.14.0/glib/poppler.h (working copy) @@ -80,6 +80,7 @@ } PopplerSelectionStyle; typedef struct _PopplerDocument PopplerDocument; +typedef struct _PopplerDocumentId PopplerDocumentId; typedef struct _PopplerIndexIter PopplerIndexIter; typedef struct _PopplerFontsIter PopplerFontsIter; typedef struct _PopplerLayersIter PopplerLayersIter; Index: poppler-0.14.0/glib/poppler-document.cc =================================================================== --- poppler-0.14.0/glib/poppler-document.cc (revision 3) +++ poppler-0.14.0/glib/poppler-document.cc (working copy) @@ -54,7 +54,9 @@ PROP_PAGE_MODE, PROP_VIEWER_PREFERENCES, PROP_PERMISSIONS, - PROP_METADATA + PROP_METADATA, + PROP_PERMANENT_ID, + PROP_UPDATE_ID }; static void poppler_document_layers_free (PopplerDocument *document); @@ -647,7 +649,8 @@ Catalog *catalog; gchar *str; guint flag; - + GooString permanent_id, update_id; + switch (prop_id) { case PROP_TITLE: @@ -762,6 +765,14 @@ } } break; + case PROP_PERMANENT_ID: + if (document->doc->getID (&permanent_id, NULL)) + g_value_set_string (value, permanent_id.getCString()); + break; + case PROP_UPDATE_ID: + if (document->doc->getID (NULL, &update_id)) + g_value_set_string (value, update_id.getCString()); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -931,6 +942,25 @@ "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 @@ -1928,7 +1958,83 @@ return NULL; } +/* PopplerDocumentId type */ +POPPLER_DEFINE_BOXED_TYPE (PopplerDocumentId, poppler_document_id, + poppler_document_id_copy, + poppler_document_id_free) + +/** + * poppler_document_id_new: + * + * creates a new #PopplerDocumentId + * + **/ +PopplerDocumentId * +poppler_document_id_new (void) +{ + return g_new0 (PopplerDocumentId, 1); +} + +/** + * poppler_document_id_copy: + * @id: a #PopplerDocumentId + * + * Creates a new #PopplerDocumentId as a copy of @id. This must be freed with + * poppler_document_id_free(). + * + * Return value: a new #PopplerDocumentId + **/ +PopplerDocumentId * +poppler_document_id_copy (PopplerDocumentId *id) +{ + PopplerDocumentId *new_id; + + g_return_val_if_fail (id != NULL, NULL); + + new_id = g_new (PopplerDocumentId, 1); + *new_id = *id; + + return new_id; +} + +/** + * poppler_document_id_free: + * @id: a #PopplerDocumentId + * + * Frees @id + * + **/ +void +poppler_document_id_free (PopplerDocumentId *id) +{ + g_free (id); +} + +/** + * poppler_document_get_id: + * @document: a #PopplerDocument + * @documentid: a #PopplerDocumentId + * + * Returns true if the pdf file contains the ID + * + * Return value: a gboolean. %TRUE if document contains an ID else %FALSE + **/ 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_convert_pdf_date_to_gtime (GooString *date, time_t *gdate) { Index: poppler-0.14.0/glib/poppler-document.h =================================================================== --- poppler-0.14.0/glib/poppler-document.h (revision 3) +++ poppler-0.14.0/glib/poppler-document.h (working copy) @@ -22,6 +22,8 @@ #include #include "poppler.h" +#define DOC_ID_LENGTH 33 // 32 bytes for each of the PDF ID (Permanent Id , Update Id) length, and 1 byte for '\0' + G_BEGIN_DECLS #define POPPLER_TYPE_DOCUMENT (poppler_document_get_type ()) @@ -89,6 +91,11 @@ } PopplerPermissions; +struct _PopplerDocumentId +{ + gchar permanent_id[DOCUMENT_ID_LENGTH]; + gchar update_id[DOCUMENT_ID_LENGTH]; +}; GType poppler_document_get_type (void) G_GNUC_CONST; @@ -122,6 +129,15 @@ PopplerFormField *poppler_document_get_form_field (PopplerDocument *document, gint id); +/* Document Id */ +#define POPPLER_TYPE_DOCUMENT_ID (poppler_document_id_get_type ()) +GType poppler_document_id_get_type (void) G_GNUC_CONST; +PopplerDocumentId *poppler_document_id_new (void); +PopplerDocumentId *poppler_document_id_copy (PopplerDocumentId *id); +void poppler_document_id_free (PopplerDocumentId *id); +gboolean poppler_document_get_id (PopplerDocument *document, + PopplerDocumentId *documentid); + /* 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;