eog r4476 - in trunk: . src



Author: friemann
Date: Tue Mar 18 19:24:15 2008
New Revision: 4476
URL: http://svn.gnome.org/viewvc/eog?rev=4476&view=rev

Log:
2008-03-18  Felix Riemann  <kirschsaft kirschsaft>

	* src/Makefile.am:
	* src/eog-metadata-reader.c: (eog_metadata_reader_get_type),
	(eog_metadata_reader_new), (eog_metadata_reader_finished),
	(eog_metadata_reader_consume), (eog_metadata_reader_get_exif_chunk),
	(eog_metadata_reader_get_exif_data), (eog_metadata_reader_get_xmp_data),
	(eog_metadata_reader_get_icc_chunk):
	* src/eog-metadata-reader.h: Make it easier to include metadata	readers
	besides the already present JPEG reader. Fixes bug #522077.


Modified:
   trunk/ChangeLog
   trunk/src/Makefile.am
   trunk/src/eog-metadata-reader.c
   trunk/src/eog-metadata-reader.h

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Tue Mar 18 19:24:15 2008
@@ -31,6 +31,7 @@
 	eog-image-private.h		\
 	eog-uri-converter.h		\
 	eog-metadata-reader.h		\
+	eog-metadata-reader-jpg.h	\
 	eog-save-as-dialog-helper.h	\
 	eog-print-image-setup.h         \
 	eog-print-preview.h             \
@@ -98,6 +99,7 @@
 	eog-jobs.c			\
 	eog-uri-converter.c		\
 	eog-metadata-reader.c		\
+	eog-metadata-reader-jpg.c	\
 	eog-save-as-dialog-helper.c	\
 	eog-print-image-setup.c         \
 	eog-print-preview.c           	\

Modified: trunk/src/eog-metadata-reader.c
==============================================================================
--- trunk/src/eog-metadata-reader.c	(original)
+++ trunk/src/eog-metadata-reader.c	Tue Mar 18 19:24:15 2008
@@ -5,127 +5,34 @@
 #include <string.h>
 
 #include "eog-metadata-reader.h"
+#include "eog-metadata-reader-jpg.h"
 #include "eog-debug.h"
 
-typedef enum {
-	EMR_READ = 0,
-	EMR_READ_SIZE_HIGH_BYTE,
-	EMR_READ_SIZE_LOW_BYTE,
-	EMR_READ_MARKER,
-	EMR_SKIP_BYTES,
-	EMR_READ_APP1,
-	EMR_READ_EXIF,
-	EMR_READ_XMP,
-	EMR_READ_ICC,
-	EMR_READ_IPTC,
-	EMR_FINISHED
-} EogMetadataReaderState;
-
-typedef enum {
-	EJA_EXIF = 0,
-	EJA_XMP,
-	EJA_OTHER
-} EogJpegApp1Type;
-
-
-#define EOG_JPEG_MARKER_START   0xFF
-#define EOG_JPEG_MARKER_SOI     0xD8
-#define EOG_JPEG_MARKER_APP1	0xE1
-#define EOG_JPEG_MARKER_APP2	0xE2
-#define EOG_JPEG_MARKER_APP14	0xED
-
-#define IS_FINISHED(priv) (priv->exif_chunk != NULL && \
-                           priv->icc_chunk  != NULL && \
-                           priv->iptc_chunk != NULL && \
-                           priv->xmp_chunk  != NULL)
-
-struct _EogMetadataReaderPrivate {
-	EogMetadataReaderState  state;
-
-	/* data fields */
-	gpointer exif_chunk;
-	guint    exif_len;
-	
-	gpointer iptc_chunk;
-	guint	 iptc_len;
-	
-	gpointer icc_chunk;
-	guint icc_len;
-
-	gpointer xmp_chunk;
-	guint xmp_len;
-	
-	/* management fields */
-	int      size;
-	int      last_marker;
-	int      bytes_read;	
-};
 
-#define EOG_METADATA_READER_GET_PRIVATE(object) \
-	(G_TYPE_INSTANCE_GET_PRIVATE ((object), EOG_TYPE_METADATA_READER, EogMetadataReaderPrivate))
-
-G_DEFINE_TYPE (EogMetadataReader, eog_metadata_reader, G_TYPE_OBJECT)
-
-static void
-eog_metadata_reader_dispose (GObject *object)
+GType
+eog_metadata_reader_get_type (void)
 {
-	EogMetadataReader *emr = EOG_METADATA_READER (object);
-	
-	if (emr->priv->exif_chunk != NULL) {
-		g_free (emr->priv->exif_chunk);
-		emr->priv->exif_chunk = NULL;
-	}
+	static GType reader_type = 0;
 
-	if (emr->priv->iptc_chunk != NULL) {
-		g_free (emr->priv->iptc_chunk);
-		emr->priv->iptc_chunk = NULL;
+	if (G_UNLIKELY (reader_type == 0)) {
+		reader_type = g_type_register_static_simple (G_TYPE_INTERFACE,
+							     "EogMetadataReader",
+							     sizeof (EogMetadataReaderInterface),
+							     NULL, 0, NULL, 0);
 	}
 
-	if (emr->priv->xmp_chunk != NULL) {
-		g_free (emr->priv->xmp_chunk);
-		emr->priv->xmp_chunk = NULL;
-	}
-
-	if (emr->priv->icc_chunk != NULL) {
-		g_free (emr->priv->icc_chunk);
-		emr->priv->icc_chunk = NULL;
-	}
-
-	G_OBJECT_CLASS (eog_metadata_reader_parent_class)->dispose (object);
-}
-
-static void
-eog_metadata_reader_init (EogMetadataReader *obj)
-{
-	EogMetadataReaderPrivate *priv;
-
-	priv = obj->priv =  EOG_METADATA_READER_GET_PRIVATE (obj);
-	priv->exif_chunk = NULL;
-	priv->exif_len = 0;
-	priv->iptc_chunk = NULL;
-	priv->iptc_len = 0;
-	priv->icc_chunk = NULL;
-	priv->icc_len = 0;
-}
-
-static void 
-eog_metadata_reader_class_init (EogMetadataReaderClass *klass)
-{
-	GObjectClass *object_class = (GObjectClass*) klass;
-
-	object_class->dispose = eog_metadata_reader_dispose;
-
-	g_type_class_add_private (klass, sizeof (EogMetadataReaderPrivate));
+	return reader_type;
 }
 
 EogMetadataReader*
 eog_metadata_reader_new (EogMetadataFileType type)
 {
-	EogMetadataReader *emr;
+	EogMetadataReader *emr = NULL;
 	
-	/* CAUTION: check for type if we support more metadat-image-formats in the future */
-	
-	emr = g_object_new (EOG_TYPE_METADATA_READER, NULL);	
+	/* CAUTION: check for type if we support more metadata-image-formats in the future */
+	if (type == EOG_METADATA_JPEG)
+		emr = EOG_METADATA_READER (eog_metadata_reader_jpg_new (type));
+
 	return emr;
 }
 
@@ -134,275 +41,14 @@
 {
 	g_return_val_if_fail (EOG_IS_METADATA_READER (emr), TRUE);
 
-	return (emr->priv->state == EMR_FINISHED);
+	return EOG_METADATA_READER_GET_INTERFACE (emr)->finished (emr);
 }
 
 
-static EogJpegApp1Type
-eog_metadata_identify_app1 (gchar *buf, guint len)
-{
- 	if (len < 5) {
- 		return EJA_OTHER;
- 	}
-
- 	if (len < 29) {
- 		return (strncmp ("Exif", buf, 5) == 0 ? EJA_EXIF : EJA_OTHER);
- 	}
-
- 	if (strncmp ("Exif", buf, 5) == 0) {
- 		return EJA_EXIF;
- 	} else if (strncmp ("http://ns.adobe.com/xap/1.0/";, buf, 29) == 0) {
- 		return EJA_XMP;
- 	}
-
- 	return EJA_OTHER;
-}
-
-static void
-eog_metadata_reader_get_next_block (EogMetadataReaderPrivate* priv,
-				    guchar *chunk,
-				    int* i,
-				    guchar *buf,
-				    int len,
-				    EogMetadataReaderState state)
-{
-	if (*i + priv->size < len) {
-		/* read data in one block */
-		memcpy ((guchar*) (chunk) + priv->bytes_read, &buf[*i], priv->size);
-		priv->state = EMR_READ;
-		*i = *i + priv->size - 1; /* the for-loop consumes the other byte */
-	} else {
-		int chunk_len = len - *i;
-		memcpy ((guchar*) (chunk) + priv->bytes_read, &buf[*i], chunk_len);
-		priv->bytes_read += chunk_len; /* bytes already read */
-		priv->size = (*i + priv->size) - len; /* remaining data to read */
-		*i = len - 1;
-		priv->state = state;
-	}
-}
-
 void
-eog_metadata_reader_consume (EogMetadataReader *emr, guchar *buf, guint len)
+eog_metadata_reader_consume (EogMetadataReader *emr, const guchar *buf, guint len)
 {
-	EogMetadataReaderPrivate *priv;
- 	EogJpegApp1Type app1_type;
-	int i;
-	EogMetadataReaderState next_state;
-	guchar *chunk = NULL;
-
-	g_return_if_fail (EOG_IS_METADATA_READER (emr));
-
-	priv = emr->priv;
-	
-	if (priv->state == EMR_FINISHED) return;
-
-	for (i = 0; (i < len) && (priv->state != EMR_FINISHED); i++) {
-
-		switch (priv->state) {
-		case EMR_READ:
-			if (buf[i] == EOG_JPEG_MARKER_START) {
-				priv->state = EMR_READ_MARKER;
-			}
-			else {
-				priv->state = EMR_FINISHED;
-			}
-			break;
-
-		case EMR_READ_MARKER:
-			if ((buf [i] & 0xF0) == 0xE0) { /* we are reading some sort of APPxx marker */
-				/* these are always followed by 2 bytes of size information */
-				priv->last_marker = buf [i];
-				priv->size = 0;
-				priv->state = EMR_READ_SIZE_HIGH_BYTE;
-
-				eog_debug_message (DEBUG_IMAGE_DATA, "APPx Marker Found: %x", priv->last_marker);
-			}
-			else {
-				/* otherwise simply consume the byte */
-				priv->state = EMR_READ;
-			}
-			break;
-			
-		case EMR_READ_SIZE_HIGH_BYTE:
-			priv->size = (buf [i] & 0xff) << 8;
-			priv->state = EMR_READ_SIZE_LOW_BYTE;
-			break;			
-			
-		case EMR_READ_SIZE_LOW_BYTE:
-			priv->size |= (buf [i] & 0xff);			
-			
-			if (priv->size > 2)  /* ignore the two size-bytes */
-				priv->size -= 2;
-		
-			if (priv->size == 0) {
-				priv->state = EMR_READ;
-			} else if (priv->last_marker == EOG_JPEG_MARKER_APP1 && 
-				   ((priv->exif_chunk == NULL) || (priv->xmp_chunk == NULL))) 
-			{
-				priv->state = EMR_READ_APP1;
-			} else if (priv->last_marker == EOG_JPEG_MARKER_APP2 && 
-				   priv->icc_chunk == NULL && priv->size > 14)
-			{
-	 			/* Chunk has 14 bytes identification data */
-				priv->state = EMR_READ_ICC;
-			} else if (priv->last_marker == EOG_JPEG_MARKER_APP14 && 
-				priv->iptc_chunk == NULL) 
-			{
-				priv->state = EMR_READ_IPTC;
-			} else {
-				priv->state = EMR_SKIP_BYTES;
-			}
-
-			priv->last_marker = 0;
-			break;			
-			
-		case EMR_SKIP_BYTES:
-			eog_debug_message (DEBUG_IMAGE_DATA, "Skip bytes: %i", priv->size);
-
-			if (i + priv->size < len) { 
-				i = i + priv->size - 1; /* the for-loop consumes the other byte */
-				priv->size = 0;
-			}
-			else {  
-				priv->size = (i + priv->size) - len;
-				i = len - 1;
-			}
-			if (priv->size == 0) { /* don't need to skip any more bytes */
-				priv->state = EMR_READ;
-			}
-			break;
-			
-		case EMR_READ_APP1:			
-			eog_debug_message (DEBUG_IMAGE_DATA, "Read APP1 data, Length: %i", priv->size);
-
-			app1_type = eog_metadata_identify_app1 ((gchar*) &buf[i], priv->size);
-			
-			switch (app1_type) {
-			case EJA_EXIF:
-				if (priv->exif_chunk == NULL) { 
-					priv->exif_chunk = g_new0 (guchar, priv->size);
-					priv->exif_len = priv->size;
-					priv->bytes_read = 0;
-					chunk = priv->exif_chunk;
-					next_state = EMR_READ_EXIF;
-				}
-				break;
-			case EJA_XMP:
-				if (priv->xmp_chunk == NULL) { 
-					priv->xmp_chunk = g_new0 (guchar, priv->size);
-					priv->xmp_len = priv->size;
-					priv->bytes_read = 0;
-					chunk = priv->xmp_chunk;
-					next_state = EMR_READ_XMP;
-				}
-				break;
-			case EJA_OTHER:
-			default:
-				/* skip unknown data */
-				priv->state = EMR_SKIP_BYTES;
-				break;
-			}
-
-			if (chunk) {
-				eog_metadata_reader_get_next_block (priv, chunk,
-								    &i, buf,
-								    len,
-								    next_state);
-			}
-
-			if (IS_FINISHED(priv))
-				priv->state = EMR_FINISHED;
-			break;
-			
-		case EMR_READ_EXIF:                     
-			eog_debug_message (DEBUG_IMAGE_DATA, "Read continuation of EXIF data, length: %i", priv->size);
-			{
- 				eog_metadata_reader_get_next_block (priv, priv->exif_chunk,
- 								    &i, buf, len, EMR_READ_EXIF);
-			}
-			if (IS_FINISHED(priv))
-				priv->state = EMR_FINISHED;
-			break;
-			
-		case EMR_READ_XMP:
-			eog_debug_message (DEBUG_IMAGE_DATA, "Read continuation of XMP data, length: %i", priv->size);
-			{
-				eog_metadata_reader_get_next_block (priv, priv->xmp_chunk,
- 								    &i, buf, len, EMR_READ_XMP);
-			}
-			if (IS_FINISHED (priv))
-				priv->state = EMR_FINISHED;
-			break;
-			
-		case EMR_READ_ICC:			
-			eog_debug_message (DEBUG_IMAGE_DATA,
-					   "Read continuation of ICC data, "
-					   "length: %i", priv->size);
-
-			if (priv->icc_chunk == NULL) { 
-				priv->icc_chunk = g_new0 (guchar, priv->size);
-				priv->icc_len = priv->size;
-				priv->bytes_read = 0;
-			}
-
-			eog_metadata_reader_get_next_block (priv,
-							    priv->icc_chunk,
-							    &i, buf, len,
-							    EMR_READ_ICC);
-
-			/* Test that the chunk actually contains ICC data. */
-			if (priv->state == EMR_READ && priv->icc_chunk) {
-			    	const char* icc_chunk = priv->icc_chunk;
-				gboolean valid = TRUE;
-
-				/* Chunk should begin with the 
-				 * ICC_PROFILE\0 identifier */
-				valid &= strncmp (icc_chunk,
-						  "ICC_PROFILE\0",12) == 0;
-				/* Make sure this is the first and only
-				 * ICC chunk in the file as we don't
-				 * support merging chunks yet. */
-				valid &=  *(guint16*)(icc_chunk+12) == 0x101;
-				
-				if (!valid) {
-					/* This no ICC data. Throw it away. */
-					eog_debug_message (DEBUG_IMAGE_DATA,
-					"Supposed ICC chunk didn't validate. "
-					"Ignoring.");
-					g_free (priv->icc_chunk);
-					priv->icc_chunk = NULL;
-					priv->icc_len = 0;
-				}
-			}
-
-			if (IS_FINISHED(priv))
-				priv->state = EMR_FINISHED;
-			break;
-			
-		case EMR_READ_IPTC:
-			eog_debug_message (DEBUG_IMAGE_DATA,
-					   "Read continuation of IPTC data, "
-					   "length: %i", priv->size);
-
-			if (priv->iptc_chunk == NULL) { 
-				priv->iptc_chunk = g_new0 (guchar, priv->size);
-				priv->iptc_len = priv->size;
-				priv->bytes_read = 0;
-			}
-
-			eog_metadata_reader_get_next_block (priv,
-							    priv->iptc_chunk,
-							    &i, buf, len,
-							    EMR_READ_IPTC);
-			
-			if (IS_FINISHED(priv))
-				priv->state = EMR_FINISHED;
-			break;
-
-		default:
-			g_assert_not_reached ();
-		}
-	}
+	EOG_METADATA_READER_GET_INTERFACE (emr)->consume (emr, buf, len);
 }
 
 /* Returns the raw exif data. NOTE: The caller of this function becomes
@@ -411,77 +57,66 @@
 void
 eog_metadata_reader_get_exif_chunk (EogMetadataReader *emr, guchar **data, guint *len)
 {
-	EogMetadataReaderPrivate *priv;
-	
-	g_return_if_fail (EOG_IS_METADATA_READER (emr));
-	priv = emr->priv;
-	
-	*data = (guchar*) priv->exif_chunk;
-	*len = priv->exif_len;
+	EogMetadataReaderInterface *iface;
+
+	g_return_if_fail (data != NULL && len != NULL);
+	iface = EOG_METADATA_READER_GET_INTERFACE (emr);
 	
-	priv->exif_chunk = NULL;
-	priv->exif_len = 0;
+	if (iface->get_raw_exif) {
+		iface->get_raw_exif (emr, data, len);
+	} else {
+		g_return_if_fail (data != NULL && len != NULL);
+
+		*data = NULL;
+		*len = 0;
+	}
+
 }
 
 #ifdef HAVE_EXIF
 ExifData*
 eog_metadata_reader_get_exif_data (EogMetadataReader *emr)
 {
-	EogMetadataReaderPrivate *priv;
-	ExifData *data = NULL;
-	
-	g_return_val_if_fail (EOG_IS_METADATA_READER (emr), NULL);
-	priv = emr->priv;
-	
-	if (priv->exif_chunk != NULL) {
-		data = exif_data_new_from_data (priv->exif_chunk, priv->exif_len);
-	}
+	gpointer exif_data = NULL;
+	EogMetadataReaderInterface *iface;
+
+	iface = EOG_METADATA_READER_GET_INTERFACE (emr);
+	if (iface->get_exif_data)
+		exif_data = iface->get_exif_data (emr);
 	
-	return data;
+	return exif_data;
 }
 #endif
 
-
 #ifdef HAVE_EXEMPI
-
-/* skip the ID + packet */
-#define EOG_XMP_OFFSET (29 + 54)
-
-XmpPtr 
+XmpPtr
 eog_metadata_reader_get_xmp_data (EogMetadataReader *emr )
 {
-	EogMetadataReaderPrivate *priv;
-	XmpPtr xmp = NULL;
+	gpointer xmp_data = NULL;
+	EogMetadataReaderInterface *iface;
 
-	g_return_val_if_fail (EOG_IS_METADATA_READER (emr), NULL);
-
-	priv = emr->priv;
-
-	if (priv->xmp_chunk != NULL) {
-		xmp = xmp_new (priv->xmp_chunk+EOG_XMP_OFFSET,
-			       priv->xmp_len-EOG_XMP_OFFSET);
-	}
+	iface = EOG_METADATA_READER_GET_INTERFACE (emr);
+	
+	if (iface->get_xmp_ptr)
+		xmp_data = iface->get_xmp_ptr (emr);
 
-	return xmp;
+	return xmp_data;
 }
 #endif
 
-/*
- * FIXME: very broken, assumes the profile fits in a single chunk.  Change to
- * parse the sections and construct a single memory chunk, or maybe even parse
- * the profile.
- */
 void
 eog_metadata_reader_get_icc_chunk (EogMetadataReader *emr, guchar **data, guint *len)
 {
-	EogMetadataReaderPrivate *priv;
-	
-	g_return_if_fail (EOG_IS_METADATA_READER (emr));
+	EogMetadataReaderInterface *iface;
 
-	priv = emr->priv;
+	g_return_if_fail (data != NULL && len != NULL);
 
-	if (priv->icc_chunk) {	
-		*data = (guchar*) priv->icc_chunk + 14;
-		*len = priv->icc_len - 14;
+	iface = EOG_METADATA_READER_GET_INTERFACE (emr);
+	
+	if (iface->get_icc_chunk)
+		iface->get_icc_chunk (emr, data, len);
+	else {
+		*data = NULL;
+		*len = 0;
 	}
 }

Modified: trunk/src/eog-metadata-reader.h
==============================================================================
--- trunk/src/eog-metadata-reader.h	(original)
+++ trunk/src/eog-metadata-reader.h	Tue Mar 18 19:24:15 2008
@@ -11,44 +11,54 @@
 
 G_BEGIN_DECLS
 
-#define EOG_TYPE_METADATA_READER            (eog_metadata_reader_get_type ())
-#define EOG_METADATA_READER(o)         (G_TYPE_CHECK_INSTANCE_CAST ((o), EOG_TYPE_METADATA_READER, EogMetadataReader))
-#define EOG_METADATA_READER_CLASS(k)   (G_TYPE_CHECK_CLASS_CAST((k), EOG_TYPE_METADATA_READER, EogMetadataReaderClass))
-#define EOG_IS_METADATA_READER(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), EOG_TYPE_METADATA_READER))
-#define EOG_IS_METADATA_READER_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), EOG_TYPE_METADATA_READER))
-#define EOG_METADATA_READER_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), EOG_TYPE_METADATA_READER, EogMetadataReaderClass))
+#define EOG_TYPE_METADATA_READER	      (eog_metadata_reader_get_type ())
+#define EOG_METADATA_READER(o)		      (G_TYPE_CHECK_INSTANCE_CAST ((o), EOG_TYPE_METADATA_READER, EogMetadataReader))
+#define EOG_IS_METADATA_READER(o)	      (G_TYPE_CHECK_INSTANCE_TYPE ((o), EOG_TYPE_METADATA_READER))
+#define EOG_METADATA_READER_GET_INTERFACE(o)  (G_TYPE_INSTANCE_GET_INTERFACE ((o), EOG_TYPE_METADATA_READER, EogMetadataReaderInterface))
 
 typedef struct _EogMetadataReader EogMetadataReader;
-typedef struct _EogMetadataReaderClass EogMetadataReaderClass;
-typedef struct _EogMetadataReaderPrivate EogMetadataReaderPrivate;
+typedef struct _EogMetadataReaderInterface EogMetadataReaderInterface;
 
-struct _EogMetadataReader {
-	GObject parent;
+struct _EogMetadataReaderInterface {
+	GTypeInterface parent;
 
-	EogMetadataReaderPrivate *priv;
-};
+	void		(*consume) 	(EogMetadataReader *self,
+					 const guchar *buf,
+					 guint len);
+
+	gboolean	(*finished) 	(EogMetadataReader *self);
+
+	void		(*get_raw_exif) (EogMetadataReader *self,
+					 guchar **data,
+					 guint *len);
 
-struct _EogMetadataReaderClass {
-	GObjectClass parent_klass;
+	gpointer	(*get_exif_data) (EogMetadataReader *self);
+
+	void		(*get_icc_chunk) (EogMetadataReader *self,
+					  guchar **data,
+					  guint *len);
+
+	gpointer	(*get_xmp_ptr) 	(EogMetadataReader *self);
 };
 
 typedef enum {
 	EOG_METADATA_JPEG
 } EogMetadataFileType;
 
-GType               eog_metadata_reader_get_type                       (void) G_GNUC_CONST;
+GType                eog_metadata_reader_get_type (void) G_GNUC_CONST;
 
 EogMetadataReader*   eog_metadata_reader_new (EogMetadataFileType type);
-void                 eog_metadata_reader_consume (EogMetadataReader *emr, guchar *buf, guint len);
+void                 eog_metadata_reader_consume (EogMetadataReader *emr, const guchar *buf, guint len);
 gboolean             eog_metadata_reader_finished (EogMetadataReader *emr);
 
 void                 eog_metadata_reader_get_exif_chunk (EogMetadataReader *emr, guchar **data, guint *len);
-#if HAVE_EXIF
+
+#ifdef HAVE_EXIF
 ExifData*            eog_metadata_reader_get_exif_data (EogMetadataReader *emr);
 #endif
 
-#if HAVE_EXEMPI
-XmpPtr               eog_metadata_reader_get_xmp_data (EogMetadataReader *emr);
+#ifdef HAVE_EXEMPI
+XmpPtr	     	     eog_metadata_reader_get_xmp_data (EogMetadataReader *emr);
 #endif
 
 #if 0



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]