[gexiv2] New call to get raw bytes of tag value: Bug #730136
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gexiv2] New call to get raw bytes of tag value: Bug #730136
- Date: Thu, 23 Oct 2014 19:17:17 +0000 (UTC)
commit a7e10b28e39d5da39cbcc2e5043d8d236ca01bd5
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]