[poppler] poppler/glib: Makefile.am, 1.10, 1.11 poppler-attachment.cc, NONE, 1.1 poppler-attachment.h, NONE, 1.1 poppler-document.cc, 1.30, 1.31 poppler-document.h, 1.17, 1.18 poppler-page.cc, 1.41, 1.42 poppler-private.h, 1.12, 1.13 poppler.h, 1.9, 1.10 test-poppler-glib.c, 1.16, 1.17

Jonathan Blandford jrb at freedesktop.org
Mon Jan 23 22:21:41 PST 2006


Update of /cvs/poppler/poppler/glib
In directory gabe:/tmp/cvs-serv25760/glib

Modified Files:
	Makefile.am poppler-document.cc poppler-document.h 
	poppler-page.cc poppler-private.h poppler.h 
	test-poppler-glib.c 
Added Files:
	poppler-attachment.cc poppler-attachment.h 
Log Message:
Tue Jan 24 01:19:40 2006  Jonathan Blandford  <jrb at redhat.com>

        * glib/Makefile.am:
        * glib/poppler-attachment.cc:
        * glib/poppler-attachment.h:
        * glib/poppler-document.cc:
        * glib/poppler-document.h:
        * glib/poppler-page.cc:
        * glib/poppler-private.h:
        * glib/poppler.h:
        * glib/test-poppler-glib.c:
        * glib/reference/tmpl/poppler-enums.sgml:
        * glib/reference/tmpl/poppler-unused.sgml: glib bindings for the
        embedded file support.  It doesn't support mtime and ctime yet,
        but the rest works.



Index: Makefile.am
===================================================================
RCS file: /cvs/poppler/poppler/glib/Makefile.am,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- Makefile.am	2 Jan 2006 00:06:46 -0000	1.10
+++ Makefile.am	24 Jan 2006 06:21:39 -0000	1.11
@@ -58,6 +58,7 @@
 	poppler-action.h			\
 	poppler-document.h			\
 	poppler-page.h				\
+	poppler-attachment.h			\
 	poppler.h
 
 poppler_glib_includedir = $(includedir)/poppler/glib
@@ -72,6 +73,7 @@
 	poppler-action.cc			\
 	poppler-document.cc			\
 	poppler-page.cc				\
+	poppler-attachment.cc			\
 	poppler.cc				\
 	poppler-private.h
 

--- NEW FILE: poppler-attachment.cc ---
/* poppler-attachment.cc: glib wrapper for poppler
 * Copyright (C) 2006, Red Hat, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "config.h"
#include <errno.h>
#include <glib/gstdio.h>

#include "poppler.h"
#include "poppler-private.h"
#include "poppler-attachment.h"

/* FIXME: We need to add gettext support sometime */
#define _(x) (x)

typedef struct _PopplerAttachmentPrivate PopplerAttachmentPrivate;
struct _PopplerAttachmentPrivate
{
  Object obj_stream;
};

#define POPPLER_ATTACHMENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), POPPLER_TYPE_ATTACHMENT, PopplerAttachmentPrivate))

static void poppler_attachment_finalize (GObject *obj);

G_DEFINE_TYPE (PopplerAttachment, poppler_attachment, G_TYPE_OBJECT);

static void
poppler_attachment_init (PopplerAttachment *attachment)
{

}

static void
poppler_attachment_class_init (PopplerAttachmentClass *klass)
{
  G_OBJECT_CLASS (klass)->finalize = poppler_attachment_finalize;
  g_type_class_add_private (klass, sizeof (PopplerAttachmentPrivate));
}

static void
poppler_attachment_finalize (GObject *obj)
{
  PopplerAttachment *attachment;

  attachment = (PopplerAttachment *) obj;
  POPPLER_ATTACHMENT_GET_PRIVATE (attachment)->obj_stream.free();
}

/* Public functions */

PopplerAttachment *
_poppler_attachment_new (PopplerDocument *document,
			 EmbFile         *emb_file)
{
  PopplerAttachment *attachment;

  g_assert (document != NULL);
  g_assert (emb_file != NULL);

  attachment = (PopplerAttachment *) g_object_new (POPPLER_TYPE_ATTACHMENT, NULL);
  
  if (emb_file->name ())
    attachment->name = g_strdup (emb_file->name ()->getCString ());
  if (emb_file->description ())
    attachment->description = g_strdup (emb_file->description ()->getCString ());

  emb_file->streamObject().copy(&POPPLER_ATTACHMENT_GET_PRIVATE (attachment)->obj_stream);

  return attachment;
}

static gboolean
save_helper (const gchar  *buf,
	     gsize         count,
	     gpointer      data,
	     GError      **error)
{
  FILE *f = (FILE *) data;
  gsize n;

  n = fwrite (buf, 1, count, f);
  if (n != count)
    {
      g_set_error (error,
		   G_FILE_ERROR,
		   g_file_error_from_errno (errno),
		   _("Error writing to image file: %s"),
		   g_strerror (errno));
      return FALSE;
    }

  return TRUE;
}

/**
 * poppler_attachment_save:
 * @attachment: A #PopplerAttachment.
 * @filename: name of file to save
 * @error: return location for error, or %NULL.
 * 
 * Saves @attachment to a file indicated by @filename.  If @error is set, %FALSE
 * will be returned. Possible errors include those in the #G_FILE_ERROR domain
 * and whatever the save function generates.
 * 
 * Return value: %TRUE, if the file successfully saved
 **/
gboolean
poppler_attachment_save (PopplerAttachment  *attachment,
			 const char         *filename,
			 GError            **error)
{
  gboolean result;
  FILE *f;
  
  g_return_val_if_fail (POPPLER_IS_ATTACHMENT (attachment), FALSE);

  f = g_fopen (filename, "wb");

  if (f == NULL)
    {
      gchar *display_name = g_filename_display_name (filename);
      g_set_error (error,
		   G_FILE_ERROR,
		   g_file_error_from_errno (errno),
		   _("Failed to open '%s' for writing: %s"),
		   display_name,
		   g_strerror (errno));
      g_free (display_name);
      return FALSE;
    }

  result = poppler_attachment_save_to_callback (attachment, save_helper, f, error);

  if (fclose (f) < 0)
    {
      gchar *display_name = g_filename_display_name (filename);
      g_set_error (error,
		   G_FILE_ERROR,
		   g_file_error_from_errno (errno),
		   _("Failed to close '%s', all data may not have been saved: %s"),
		   display_name,
		   g_strerror (errno));
      g_free (display_name);
      return FALSE;
    }

  return TRUE;
}

#define BUF_SIZE 1024

/**
 * poppler_attachment_save_to_callback:
 * @attachment: A #GdkPixbuf.
 * @save_func: a function that is called to save each block of data that the save routine generates.
 * @user_data: user data to pass to the save function.
 * @error: return location for error, or %NULL.
 * 
 * Saves @attachment by feeding the produced data to @save_func. Can be used
 * when you want to store the attachment to something other than a file, such as
 * an in-memory buffer or a socket. If @error is set, %FALSE will be
 * returned. Possible errors include those in the #G_FILE_ERROR domain and
 * whatever the save function generates.
 * 
 * Return value: %TRUE, if the save successfully completed
 **/
gboolean
poppler_attachment_save_to_callback (PopplerAttachment          *attachment,
				     PopplerAttachmentSaveFunc   save_func,
				     gpointer                    user_data,
				     GError                    **error)
{
  Stream *stream;
  gchar buf[BUF_SIZE]; 
  int i;
  gboolean eof_reached = FALSE;

  g_return_val_if_fail (POPPLER_IS_ATTACHMENT (attachment), FALSE);

  stream = POPPLER_ATTACHMENT_GET_PRIVATE (attachment)->obj_stream.getStream();
  stream->reset();

  do
    {
      int data;

      for (i = 0; i < BUF_SIZE; i++)
	{
	  data = stream->getChar ();
	  if (data == EOF)
	    {
	      eof_reached = TRUE;
	      break;
	    }
	  buf[i] = data;
	}

      if (i > 0)
	{
	  if (! (save_func) (buf, i, user_data, error))
	    return FALSE;
	}
    }
  while (! eof_reached);


  return TRUE;
}

--- NEW FILE: poppler-attachment.h ---
/* poppler-attachment.h: glib interface to poppler
 * Copyright (C) 2004, Red Hat, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef __POPPLER_ATTACHMENT_H__
#define __POPPLER_ATTACHMENT_H__

#include <glib-object.h>

#include "poppler.h"

G_BEGIN_DECLS


#define POPPLER_TYPE_ATTACHMENT             (poppler_attachment_get_type ())
#define POPPLER_ATTACHMENT(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ATTACHMENT, PopplerAttachment))
#define POPPLER_IS_ATTACHMENT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ATTACHMENT))


typedef gboolean (*PopplerAttachmentSaveFunc) (const gchar  *buf,
					       gsize         count,
					       gpointer      data,
					       GError      **error);

typedef struct _PopplerAttachment
{
  GObject parent;

  const char *name;
  const char *description;
  time_t mtime;
  time_t ctime;
} PopplerAttachment;

typedef struct _PopplerAttachmentClass
{
  GObjectClass parent_class;
} PopplerAttachmentClass;


GType     poppler_attachment_get_type         (void) G_GNUC_CONST;
gboolean  poppler_attachment_save             (PopplerAttachment          *attachment,
					       const char                 *filename,
					       GError                    **error);
gboolean  poppler_attachment_save_to_callback (PopplerAttachment          *attachment,
					       PopplerAttachmentSaveFunc   save_func,
					       gpointer                    user_data,
					       GError                    **error);


G_END_DECLS

#endif /* __POPPLER_ATTACHMENT_H__ */

Index: poppler-document.cc
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-document.cc,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- poppler-document.cc	18 Jan 2006 22:32:13 -0000	1.30
+++ poppler-document.cc	24 Jan 2006 06:21:39 -0000	1.31
@@ -32,6 +32,7 @@
 
 #include "poppler.h"
 #include "poppler-private.h"
+#include "poppler-attachment.h"
 #include "poppler-enums.h"
 
 enum {
@@ -252,6 +253,68 @@
   return poppler_document_get_page (document, index);
 }
 
+/**
+ * poppler_document_has_attachments:
+ * @document: A #PopplerDocument
+ * 
+ * Returns %TRUE of @document has any attachments.
+ * 
+ * Return value: %TRUE, if @document has attachments.
+ **/
+gboolean
+poppler_document_has_attachments (PopplerDocument *document)
+{
+  Catalog *catalog;
+  int n_files = 0;
+
+  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), FALSE);
+
+  catalog = document->doc->getCatalog ();
+  if (catalog && catalog->isOk ())
+    {
+      n_files = catalog->numEmbeddedFiles ();
+    }
+
+  return (n_files != 0);
+}
+
+/**
+ * poppler_document_get_attachments:
+ * @document: A #PopplerDocument
+ * 
+ * Returns a #GList containing #PopplerAttachment<!-- -->s.  These attachments
+ * are unowned, and must be unreffed, and the list must be freed with
+ * g_list_free().
+ * 
+ * Return value: a list of available attachments.
+ **/
+GList *
+poppler_document_get_attachments (PopplerDocument *document)
+{
+  Catalog *catalog;
+  int n_files, i;
+  GList *retval = NULL;
+
+  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);
+
+  catalog = document->doc->getCatalog ();
+  if (catalog == NULL || ! catalog->isOk ())
+    return NULL;
+
+  n_files = catalog->numEmbeddedFiles ();
+  for (i = 0; i < n_files; i++)
+    {
+      PopplerAttachment *attachment;
+      EmbFile *emb_file;
+
+      emb_file = catalog->embeddedFile (i);
+      attachment = _poppler_attachment_new (document, emb_file);
+
+      retval = g_list_prepend (retval, attachment);
+    }
+  return g_list_reverse (retval);
+}
+
 static gboolean
 has_unicode_marker (GooString *string)
 {

Index: poppler-document.h
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-document.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- poppler-document.h	31 Dec 2005 02:10:33 -0000	1.17
+++ poppler-document.h	24 Jan 2006 06:21:39 -0000	1.18
@@ -100,6 +100,10 @@
 						     int               index);
 PopplerPage     *poppler_document_get_page_by_label (PopplerDocument  *document,
 						     const char       *label);
+/* Attachments */
+gboolean         poppler_document_has_attachments   (PopplerDocument  *document);
+GList           *poppler_document_get_attachments   (PopplerDocument  *document);
+
 
 
 /* Interface for getting the Index of a poppler_document */
@@ -142,6 +146,8 @@
                                                gboolean         duplex);
 void           poppler_ps_file_free           (PopplerPSFile   *ps_file);
 
+
+
 G_END_DECLS
 
 #endif /* __POPPLER_DOCUMENT_H__ */

Index: poppler-page.cc
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-page.cc,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- poppler-page.cc	31 Dec 2005 02:10:33 -0000	1.41
+++ poppler-page.cc	24 Jan 2006 06:21:39 -0000	1.42
@@ -1,4 +1,4 @@
-/* poppler.h: glib wrapper for poppler
+/* poppler-page.cc: glib wrapper for poppler
  * Copyright (C) 2005, Red Hat, Inc.
  *
  * This program is free software; you can redistribute it and/or modify

Index: poppler-private.h
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-private.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- poppler-private.h	22 Aug 2005 18:20:12 -0000	1.12
+++ poppler-private.h	24 Jan 2006 06:21:39 -0000	1.13
@@ -8,6 +8,9 @@
 #include <Gfx.h>
 #include <FontInfo.h>
 #include <TextOutputDev.h>
+#include <Catalog.h>
+
+#include "poppler-attachment.h"
 
 #if defined (HAVE_CAIRO)
 #include <CairoOutputDev.h>
@@ -62,5 +65,6 @@
 				    LinkAction      *link,
 				    const gchar     *title);
 
-
+PopplerAttachment *_poppler_attachment_new (PopplerDocument *document,
+					    EmbFile         *file);
 #endif

Index: poppler.h
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- poppler.h	20 Jun 2005 17:58:38 -0000	1.9
+++ poppler.h	24 Jan 2006 06:21:39 -0000	1.10
@@ -69,5 +69,6 @@
 #include "poppler-page.h"
 #include "poppler-action.h"
 #include "poppler-enums.h"
+#include "poppler-attachment.h"
 
 #endif /* __POPPLER_GLIB_H__ */

Index: test-poppler-glib.c
===================================================================
RCS file: /cvs/poppler/poppler/glib/test-poppler-glib.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- test-poppler-glib.c	23 Jan 2006 15:40:54 -0000	1.16
+++ test-poppler-glib.c	24 Jan 2006 06:21:39 -0000	1.17
@@ -198,7 +198,31 @@
 
       printf ("  (%f,%f)-(%f,%f)\n", rect->x1, rect->y1, rect->x2, rect->y2);
     }
-    
+
+  if (poppler_document_has_attachments (document))
+    {
+      int i = 0;
+
+      g_print ("Attachments found:\n\n");
+
+      list = poppler_document_get_attachments (document);
+      for (l = list; l; l = l->next)
+	{
+	  PopplerAttachment *attachment;
+	  char *name;
+
+	  name = g_strdup_printf ("/tmp/attach%d", i);
+	  attachment = l->data;
+	  g_print ("\tname: %s\n", attachment->name);
+	  g_print ("\tdescription: %s\n\n", attachment->description);
+	  poppler_attachment_save (attachment, name, NULL);
+	  i++;
+	}
+      g_list_foreach (list, g_object_unref, NULL);
+      g_list_free (list);
+    }
+  else
+    g_print ("no attachment\n");
 
   g_object_unref (G_OBJECT (page));
 



More information about the poppler mailing list