eog r4476 - in trunk: . src
- From: friemann svn gnome org
- To: svn-commits-list gnome org
- Subject: eog r4476 - in trunk: . src
- Date: Tue, 18 Mar 2008 19:24:16 +0000 (GMT)
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]