[gexiv2/gexiv2-0.10] New call to get raw bytes of tag value: Bug #730136



commit 342c03dfc027f612543bd57ce15e02d9353574b9
Author: Alexandre Rossi <alexandre rossi gmail com>
Date:   Thu Oct 23 12:16:25 2014 -0700

    New call to get raw bytes of tag value: Bug #730136

 .gitignore                         |    3 ++
 GExiv2.py                          |    3 ++
 Makefile.am                        |   15 +++++++++-
 THANKS                             |    1 +
 gexiv2.vapi                        |    1 +
 gexiv2/gexiv2-metadata-exif.cpp    |   27 ++++++++++++++++++
 gexiv2/gexiv2-metadata-iptc.cpp    |   27 ++++++++++++++++++
 gexiv2/gexiv2-metadata-private.h   |    5 +++
 gexiv2/gexiv2-metadata-xmp.cpp     |   27 ++++++++++++++++++
 gexiv2/gexiv2-metadata.cpp         |   17 +++++++++++
 gexiv2/gexiv2-metadata.h           |   10 +++++++
 test/python/gexiv2.py              |   53 ++++++++++++++++++++++++++++++++++++
 test/sample-author-badencoding.jpg |  Bin 0 -> 614 bytes
 vapi/gexiv2.metadata               |    1 +
 14 files changed, 188 insertions(+), 2 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 6ed0a8e..2b9a37c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,9 @@ gexiv2/gexiv2-version.h
 /GExiv2-*.*.typelib
 vapi/gexiv2.gi
 test/gexiv2-dump
+test/python/gi
+*.pyc
+__pycache__
 
 # Autotools files.
 /Makefile.in
diff --git a/GExiv2.py b/GExiv2.py
index 3bab147..2948112 100644
--- a/GExiv2.py
+++ b/GExiv2.py
@@ -78,6 +78,9 @@ class Metadata(GExiv2.Metadata):
     
     def get(self, key, default=None):
         return self.get_tag_string(key) if self.has_tag(key) else default
+
+    def get_raw(self, key):
+        return self.get_tag_raw(key).get_data()
     
     def __iter__(self):
         return iter(self.get_tags())
diff --git a/Makefile.am b/Makefile.am
index 9f4efc7..cf64526 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,7 +16,10 @@ EXTRA_DIST = \
        @PACKAGE_NAME  vapi             \
        gexiv2/gexiv2-version.m4 \
        $(TYPELIB_FILES) \
-       test/gexiv2-dump.vala
+       test/sample-author-badencoding.jpg \
+       test/gexiv2-dump.vala \
+       test/python/gexiv2.py
+
 
 # Installed Files #
 pkgconfig_DATA  = @PACKAGE_NAME  pc
@@ -105,16 +108,24 @@ clean-local:
        rm -f gexiv2/gexiv2-version.h
        rm -f gexiv2.pc
        rm -f test/gexiv2-dump
+       rm -rf test/python/gi test/python/__pycache__
 
 # Tests and utilities #
 
 if ENABLE_TESTS
 
-tests: test/gexiv2-dump
+tests: test/gexiv2-dump test/python2 test/python3
 
 test/gexiv2-dump: test/gexiv2-dump.vala
        valac -g --enable-checking --vapidir=. --pkg gexiv2 $< -o $@
 
+test/python/gi/overrides/GExiv2.py:
+       [ -d $(dir $@) ] || mkdir -p $(dir $@)
+       ln -sf ../../../../GExiv2.py $@
+
+test/python%: $(TYPELIB_FILES) test/python/gi/overrides/GExiv2.py
+       LD_LIBRARY_PATH=.libs GI_TYPELIB_PATH=. PYTHONPATH=test/python python$* -m unittest gexiv2
+
 endif
 
 # Optional Introspection #
diff --git a/THANKS b/THANKS
index b86755d..8a7e87e 100644
--- a/THANKS
+++ b/THANKS
@@ -12,6 +12,7 @@ Michael Pratt <michael prattmic com>
 John Ralls <jralls ceridwen us>
 Akhil Ravidas <deepblue ar gmail com>
 Clint Rogers <clinton yorba org>
+Alexandre Rossi <alexandre rossi gmail com>
 Alexandre Rostovtsev <tetromino gmail com>
 Ankur Sinha <sanjay ankur gmail com>
 Alexander Steffen
diff --git a/gexiv2.vapi b/gexiv2.vapi
index 5a52e33..9e1cb6d 100644
--- a/gexiv2.vapi
+++ b/gexiv2.vapi
@@ -62,6 +62,7 @@ namespace GExiv2 {
                public long get_tag_long (string tag);
                [CCode (array_length = false, array_null_terminated = true)]
                public string[]? get_tag_multiple (string tag);
+               public GLib.Bytes? get_tag_raw (string tag);
                public string? get_tag_string (string tag);
                public static unowned string get_tag_type (string tag);
                public string? get_xmp_packet ();
diff --git a/gexiv2/gexiv2-metadata-exif.cpp b/gexiv2/gexiv2-metadata-exif.cpp
index 12aba5a..8084575 100644
--- a/gexiv2/gexiv2-metadata-exif.cpp
+++ b/gexiv2/gexiv2-metadata-exif.cpp
@@ -293,4 +293,31 @@ const gchar* gexiv2_metadata_get_exif_tag_type (const gchar* tag) {
     return NULL;
 }
 
+GBytes* gexiv2_metadata_get_exif_tag_raw (GExiv2Metadata *self, const gchar* tag) {
+    g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
+    g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+
+    Exiv2::ExifData &exif_data = self->priv->image->exifData();
+
+    try {
+        Exiv2::ExifData::iterator it = exif_data.findKey(Exiv2::ExifKey(tag));
+        while (it != exif_data.end() && it->count() == 0)
+            it++;
+
+        if (it != exif_data.end()) {
+            long size = it->size();
+            if( size > 0 ) {
+                gpointer data = g_malloc(size);
+                it->copy((Exiv2::byte*)data, Exiv2::invalidByteOrder);
+                return g_bytes_new_take(data, size);
+            }
+        }
+    } catch (Exiv2::Error& e) {
+        LOG_ERROR(e);
+    }
+
+    return NULL;
+}
+
 G_END_DECLS
diff --git a/gexiv2/gexiv2-metadata-iptc.cpp b/gexiv2/gexiv2-metadata-iptc.cpp
index 0329422..2371708 100644
--- a/gexiv2/gexiv2-metadata-iptc.cpp
+++ b/gexiv2/gexiv2-metadata-iptc.cpp
@@ -277,4 +277,31 @@ const gchar* gexiv2_metadata_get_iptc_tag_type (const gchar* tag) {
     return NULL;
 }
 
+GBytes* gexiv2_metadata_get_iptc_tag_raw (GExiv2Metadata *self, const gchar* tag) {
+    g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
+    g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+
+    Exiv2::IptcData& iptc_data = self->priv->image->iptcData();
+
+    try {
+        Exiv2::IptcData::iterator it = iptc_data.findKey(Exiv2::IptcKey(tag));
+        while (it != iptc_data.end() && it->count() == 0)
+            it++;
+
+        if (it != iptc_data.end()) {
+            long size = it->size();
+            if( size > 0 ) {
+                gpointer data = g_malloc(size);
+                it->copy((Exiv2::byte*)data, Exiv2::invalidByteOrder);
+                return g_bytes_new_take(data, size);
+            }
+        }
+    } catch (Exiv2::Error& e) {
+        LOG_ERROR(e);
+    }
+
+    return NULL;
+}
+
 G_END_DECLS
diff --git a/gexiv2/gexiv2-metadata-private.h b/gexiv2/gexiv2-metadata-private.h
index 03f8324..16d38ef 100644
--- a/gexiv2/gexiv2-metadata-private.h
+++ b/gexiv2/gexiv2-metadata-private.h
@@ -50,6 +50,8 @@ const gchar*  gexiv2_metadata_get_exif_tag_label      (const gchar* tag);
 const gchar*   gexiv2_metadata_get_exif_tag_description (const gchar* tag);
 const gchar*   gexiv2_metadata_get_exif_tag_type (const gchar* tag);
 
+GBytes*                        gexiv2_metadata_get_exif_tag_raw        (GExiv2Metadata *self, const gchar* 
tag);
+
 /* private XMP functions */
 
 gboolean               gexiv2_metadata_clear_xmp_tag           (GExiv2Metadata *self, const gchar* tag);
@@ -66,6 +68,8 @@ const gchar*  gexiv2_metadata_get_xmp_tag_label               (const gchar* tag);
 const gchar*   gexiv2_metadata_get_xmp_tag_description (const gchar* tag);
 const gchar*   gexiv2_metadata_get_xmp_tag_type        (const gchar* tag);
 
+GBytes*                        gexiv2_metadata_get_xmp_tag_raw         (GExiv2Metadata *self, const gchar* 
tag);
+
 /* private IPTC functions */
 
 gboolean               gexiv2_metadata_clear_iptc_tag          (GExiv2Metadata *self, const gchar* tag);
@@ -80,6 +84,7 @@ const gchar*  gexiv2_metadata_get_iptc_tag_label      (const gchar* tag);
 const gchar*   gexiv2_metadata_get_iptc_tag_description        (const gchar* tag);
 const gchar*   gexiv2_metadata_get_iptc_tag_type       (const gchar* tag);
 
+GBytes*                        gexiv2_metadata_get_iptc_tag_raw        (GExiv2Metadata *self, const gchar* 
tag);
 
 G_END_DECLS
 
diff --git a/gexiv2/gexiv2-metadata-xmp.cpp b/gexiv2/gexiv2-metadata-xmp.cpp
index 4fc8077..565e098 100644
--- a/gexiv2/gexiv2-metadata-xmp.cpp
+++ b/gexiv2/gexiv2-metadata-xmp.cpp
@@ -369,6 +369,33 @@ const gchar* gexiv2_metadata_get_xmp_tag_type (const gchar* tag) {
     return NULL;
 }
 
+GBytes* gexiv2_metadata_get_xmp_tag_raw (GExiv2Metadata *self, const gchar* tag) {
+    g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
+    g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+
+    Exiv2::XmpData& xmp_data = self->priv->image->xmpData();
+
+    try {
+        Exiv2::XmpData::iterator it = xmp_data.findKey(Exiv2::XmpKey(tag));
+        while (it != xmp_data.end() && it->count() == 0)
+            it++;
+
+        if (it != xmp_data.end()) {
+            long size = it->size();
+            if( size > 0 ) {
+                gpointer data = g_malloc(size);
+                it->copy((Exiv2::byte*)data, Exiv2::invalidByteOrder);
+                return g_bytes_new_take(data, size);
+            }
+        }
+    } catch (Exiv2::Error& e) {
+        LOG_ERROR(e);
+    }
+
+    return NULL;
+}
+
 gboolean gexiv2_metadata_register_xmp_namespace (const gchar* name, const gchar* prefix) {
     g_return_val_if_fail(name != NULL, FALSE);
     g_return_val_if_fail(prefix != NULL, FALSE);
diff --git a/gexiv2/gexiv2-metadata.cpp b/gexiv2/gexiv2-metadata.cpp
index fc7bcb4..3e26a05 100644
--- a/gexiv2/gexiv2-metadata.cpp
+++ b/gexiv2/gexiv2-metadata.cpp
@@ -868,4 +868,21 @@ const gchar* gexiv2_metadata_get_tag_type (const gchar *tag) {
     return NULL;
 }
 
+GBytes* gexiv2_metadata_get_tag_raw(GExiv2Metadata *self, const gchar* tag) {
+    g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
+    g_return_val_if_fail(tag != NULL, NULL);
+    g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+
+    if (gexiv2_metadata_is_xmp_tag(tag))
+        return gexiv2_metadata_get_xmp_tag_raw(self, tag);
+
+    if (gexiv2_metadata_is_exif_tag(tag))
+        return gexiv2_metadata_get_exif_tag_raw(self, tag);
+
+    if (gexiv2_metadata_is_iptc_tag(tag))
+        return gexiv2_metadata_get_iptc_tag_raw(self, tag);
+
+    return NULL;
+}
+
 G_END_DECLS
diff --git a/gexiv2/gexiv2-metadata.h b/gexiv2/gexiv2-metadata.h
index 1c2fd7d..3a28a2b 100644
--- a/gexiv2/gexiv2-metadata.h
+++ b/gexiv2/gexiv2-metadata.h
@@ -429,6 +429,16 @@ gchar**                    gexiv2_metadata_get_tag_multiple        (GExiv2Metadata 
*self, const gchar* t
 gboolean               gexiv2_metadata_set_tag_multiple        (GExiv2Metadata *self, const gchar* tag, 
const gchar** values);
 
 /**
+ * gexiv2_metadata_get_tag_raw:
+ * @tag: Exiv2 tag name
+ *
+ * The Exiv2 Tag Reference can be found at http://exiv2.org/metadata.html
+ *
+ * Returns: (transfer full) (allow-none): The tag's raw value as a byte array
+ */
+GBytes*                        gexiv2_metadata_get_tag_raw                     (GExiv2Metadata *self, const 
gchar* tag);
+
+/**
  * EXIF functions
  */
 
diff --git a/test/python/gexiv2.py b/test/python/gexiv2.py
new file mode 100644
index 0000000..9048f08
--- /dev/null
+++ b/test/python/gexiv2.py
@@ -0,0 +1,53 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+#
+# Copyright (C) 2014 Alexandre Rossi <alexandre rossi gmail com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+# USA
+
+
+import unittest
+import os
+
+
+# Workaround pkutil.extend_path in dist-packages/gi/overrides/__init__.py
+# not helping us here for obscure reasons when using python2 (the following
+# is useless in python3).
+import gi.overrides
+gi.overrides.__path__.append(os.path.join(os.path.dirname(__file__),
+                                          'gi', 'overrides'))
+
+
+from gi.repository import GExiv2
+
+
+SAMPLES_DIR = os.path.join(os.path.dirname(__file__), '..')
+
+
+class TestGexiv2(unittest.TestCase):
+
+    def get_sample_path(self, sample):
+        return os.path.join(SAMPLES_DIR, sample)
+
+    def test_author_badencoding(self):
+        sample = 'sample-author-badencoding.jpg'
+        md = GExiv2.Metadata(self.get_sample_path(sample))
+
+        self.assertEqual(md.get_raw('Exif.Image.Artist'), b'\xc0\xeb\xe5\xea\xf1\xe0\xed\xe4\xf0 
\xca\xee\xf8\xe5\xeb\xe5\xe2\x00')
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/test/sample-author-badencoding.jpg b/test/sample-author-badencoding.jpg
new file mode 100644
index 0000000..c13e37b
Binary files /dev/null and b/test/sample-author-badencoding.jpg differ
diff --git a/vapi/gexiv2.metadata b/vapi/gexiv2.metadata
index 60934cf..0a137f3 100644
--- a/vapi/gexiv2.metadata
+++ b/vapi/gexiv2.metadata
@@ -24,6 +24,7 @@ gexiv2_metadata_get_tag_multiple is_array="1" array_null_terminated="1" transfer
 gexiv2_metadata_set_tag_multiple.values is_array="1" array_null_terminated="1"
 gexiv2_metadata_get_tag_label nullable="1" transfer_ownership="0"
 gexiv2_metadata_get_tag_description nullable="1" transfer_ownership="0"
+gexiv2_metadata_get_tag_raw transfer_ownership="1" nullable="1"
 
 gexiv2_metadata_get_exposure_time.nom is_out="1"
 gexiv2_metadata_get_exposure_time.den is_out="1"


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