[niepce] Issue #35 - Fill the aux:Lens property as well



commit 6ddf74f8dc6c03dd7b57881cb287c72e7c440d3e
Author: Hubert Figuière <hub figuiere net>
Date:   Mon Dec 24 22:06:38 2018 -0500

    Issue #35 - Fill the aux:Lens property as well
    
    https://gitlab.gnome.org/GNOME/niepce/issues/35

 Cargo.lock             |  10 +++++
 Cargo.toml             |   3 +-
 build.rs               |   2 +-
 src/fwk/utils/exiv2.rs | 116 ++++++++++++++++++++++++++-----------------------
 src/lib.rs             |   1 +
 5 files changed, 75 insertions(+), 57 deletions(-)
---
diff --git a/Cargo.lock b/Cargo.lock
index 606a47a..2334d0b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -482,6 +482,14 @@ dependencies = [
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "multimap"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "serde 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "niepce_rust"
 version = "0.1.0"
@@ -499,6 +507,7 @@ dependencies = [
  "gtk-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "rexiv2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rusqlite 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1006,6 +1015,7 @@ dependencies = [
 "checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21"
 "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
 "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
+"checksum multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"2eb04b9f127583ed176e163fb9ec6f3e793b87e21deedd5734a69386a18a0151"
 "checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b"
 "checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = 
"4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
 "checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = 
"f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe"
diff --git a/Cargo.toml b/Cargo.toml
index 068e3b0..3d18fc0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,6 +16,7 @@ gtk-sys = { version = "0.7.0", features = ["v3_16"] }
 gtk = "0.5.0"
 lazy_static = "^1.2.0"
 libc = "0.2.39"
+multimap = "0.4.0"
 rexiv2 = "^0.6.0"
 rusqlite = { version = "0.14.0", features = ["functions"] }
 try_opt = "0.1.1"
@@ -28,4 +29,4 @@ pkg-config = "0.3.9"
 
 [lib]
 name = "niepce_rust"
-crate-type = ["staticlib"]
+crate-type = ["staticlib"]
\ No newline at end of file
diff --git a/build.rs b/build.rs
index 9d1c335..c7d578b 100644
--- a/build.rs
+++ b/build.rs
@@ -67,7 +67,7 @@ fn main() {
             .with_namespace("ffi")
             .with_language(cbindgen::Language::Cxx)
             .with_parse_deps(true)
-            .with_parse_exclude(&["exempi", "chrono"])
+            .with_parse_exclude(&["exempi", "chrono", "multimap"])
             .exclude_item("GtkWindow")
             .exclude_item("GtkToolbar")
             .exclude_item("GFileInfo")
diff --git a/src/fwk/utils/exiv2.rs b/src/fwk/utils/exiv2.rs
index 5f07b73..639e3f1 100644
--- a/src/fwk/utils/exiv2.rs
+++ b/src/fwk/utils/exiv2.rs
@@ -18,12 +18,12 @@
  */
 
 use std::ffi::OsStr;
-use std::collections::HashMap;
+use multimap::MultiMap;
 
 use exempi;
 use rexiv2;
 
-use super::exempi::{Flash, XmpMeta, NS_TIFF, NS_EXIF, NS_EXIF_EX, NS_XAP, xmp_date_from_exif};
+use super::exempi::{Flash, XmpMeta, NS_TIFF, NS_EXIF, NS_EXIF_EX, NS_AUX, NS_XAP, xmp_date_from_exif};
 
 /// Property conversion rules
 #[derive(Clone, Copy, Debug)]
@@ -50,7 +50,7 @@ enum Converted {
 }
 
 lazy_static! {
-    static ref exiv2_to_xmp: HashMap<&'static str, (&'static str, &'static str, Conversion)> = {
+    static ref exiv2_to_xmp: MultiMap<&'static str, (&'static str, &'static str, Conversion)> = {
         [
             ("Exif.Image.DateTime", (NS_XAP, "ModifyDate", Conversion::ExifDate)),
             ("Exif.Image.ImageHeight", (NS_TIFF, "ImageHeight", Conversion::None)),
@@ -75,6 +75,7 @@ lazy_static! {
             ("Exif.Photo.FocalLengthIn35mmFilm", (NS_EXIF, "FocalLengthIn35mmFilm", Conversion::None)),
             ("Exif.Photo.ISOSpeedRatings", (NS_EXIF, "ISOSpeedRatings", Conversion::None)),
             ("Exif.Photo.LensMake", (NS_EXIF_EX, "LensMake", Conversion::None)),
+            ("Exif.Photo.LensModel", (NS_AUX, "Lens", Conversion::None)),
             ("Exif.Photo.LensModel", (NS_EXIF_EX, "LensModel", Conversion::None)),
             ("Exif.Photo.LensSerialNumber", (NS_EXIF_EX, "LensSerialNumber", Conversion::None)),
             ("Exif.Photo.LensSpecification", (NS_EXIF_EX, "LensSpecification", Conversion::None)),
@@ -85,11 +86,14 @@ lazy_static! {
             ("Exif.Photo.UserComment", (NS_EXIF, "UserComment", Conversion::None)),
             ("Exif.Photo.WhiteBalance", (NS_EXIF, "WhiteBalance", Conversion::None)),
 
+            ("Exif.Canon.LensModel", (NS_AUX, "Lens", Conversion::None)),
             ("Exif.Canon.LensModel", (NS_EXIF_EX, "LensModel", Conversion::None)),
 
+            ("Exif.OlympusEq.LensModel", (NS_AUX, "Lens", Conversion::None)),
             ("Exif.OlympusEq.LensModel", (NS_EXIF_EX, "LensModel", Conversion::None)),
             ("Exif.OlympusEq.LensSerialNumber", (NS_EXIF_EX, "LensSerialNumber", Conversion::None)),
 
+            ("Exif.Pentax.LensType", (NS_AUX, "Lens", Conversion::None)),
             ("Exif.Pentax.LensType", (NS_EXIF_EX, "LensModel", Conversion::None))
         ].iter().cloned().collect()
     };
@@ -131,65 +135,67 @@ pub fn xmp_from_exiv2<S: AsRef<OsStr>>(file: S) -> Option<XmpMeta> {
             all_tags.append(&mut tags);
         }
         for tag in all_tags {
-            if let Some(xmp_prop) = exiv2_to_xmp.get(tag.as_str()) {
-                let tagtype = rexiv2::get_tag_type(&tag);
-                match tagtype {
-                    Ok(rexiv2::TagType::AsciiString) => {
-                        if let Ok(value) = meta.get_tag_string(&tag) {
-                            let converted = convert(xmp_prop.2, &value);
-                            match converted {
-                                Converted::Str(s) => {
-                                    xmp.set_property(xmp_prop.0, xmp_prop.1, &s, exempi::PROP_NONE);
-                                },
-                                Converted::Date(d) => {
-                                    if let Some(d) = d {
-                                        xmp.set_property_date(xmp_prop.0, xmp_prop.1, &d, exempi::PROP_NONE);
-                                    } else {
-                                        err_out!("Couldn't convert Exif date {}", &value);
+            if let Some(xmp_props) = exiv2_to_xmp.get_vec(tag.as_str()) {
+                for xmp_prop in xmp_props {
+                    let tagtype = rexiv2::get_tag_type(&tag);
+                    match tagtype {
+                        Ok(rexiv2::TagType::AsciiString) => {
+                            if let Ok(value) = meta.get_tag_string(&tag) {
+                                let converted = convert(xmp_prop.2, &value);
+                                match converted {
+                                    Converted::Str(s) => {
+                                        xmp.set_property(xmp_prop.0, xmp_prop.1, &s, exempi::PROP_NONE);
+                                    },
+                                    Converted::Date(d) => {
+                                        if let Some(d) = d {
+                                            xmp.set_property_date(xmp_prop.0, xmp_prop.1, &d, 
exempi::PROP_NONE);
+                                        } else {
+                                            err_out!("Couldn't convert Exif date {}", &value);
+                                        }
+                                    },
+                                    _ => {
+                                        err_out!("Unknown conversion result {:?}", &converted);
                                     }
+                                }
+                            }
+                        },
+                        Ok(rexiv2::TagType::UnsignedShort) |
+                        Ok(rexiv2::TagType::UnsignedLong) |
+                        Ok(rexiv2::TagType::SignedShort) |
+                        Ok(rexiv2::TagType::SignedLong) => {
+                            // XXX rexiv2 returns an i32, which is a problem for UnsignedLong
+                            match xmp_prop.2 {
+                                Conversion::Flash => {
+                                    if let Converted::Flash(flash) = convert_int(xmp_prop.2, 
meta.get_tag_numeric(&tag)) {
+                                        flash.set_as_xmp_property(&mut xmp, NS_EXIF, "Flash");
+                                    }
+                                },
+                                Conversion::None => {
+                                    let value = meta.get_tag_numeric(&tag);
+                                    xmp.set_property_i32(xmp_prop.0, xmp_prop.1, value, exempi::PROP_NONE);
                                 },
                                 _ => {
-                                    err_out!("Unknown conversion result {:?}", &converted);
+                                    err_out!("Unknown conversion from {:?} to {:?}", tagtype, xmp_prop.2);
+                                    let value = meta.get_tag_numeric(&tag);
+                                    xmp.set_property_i32(xmp_prop.0, xmp_prop.1, value, exempi::PROP_NONE);
                                 }
                             }
-                        }
-                    },
-                    Ok(rexiv2::TagType::UnsignedShort) |
-                    Ok(rexiv2::TagType::UnsignedLong) |
-                    Ok(rexiv2::TagType::SignedShort) |
-                    Ok(rexiv2::TagType::SignedLong) => {
-                        // XXX rexiv2 returns an i32, which is a problem for UnsignedLong
-                        match xmp_prop.2 {
-                            Conversion::Flash => {
-                                if let Converted::Flash(flash) = convert_int(xmp_prop.2, 
meta.get_tag_numeric(&tag)) {
-                                    flash.set_as_xmp_property(&mut xmp, NS_EXIF, "Flash");
-                                }
-                            },
-                            Conversion::None => {
-                                let value = meta.get_tag_numeric(&tag);
-                                xmp.set_property_i32(xmp_prop.0, xmp_prop.1, value, exempi::PROP_NONE);
-                            },
-                            _ => {
-                                err_out!("Unknown conversion from {:?} to {:?}", tagtype, xmp_prop.2);
-                                let value = meta.get_tag_numeric(&tag);
-                                xmp.set_property_i32(xmp_prop.0, xmp_prop.1, value, exempi::PROP_NONE);
+                        },
+                        Ok(rexiv2::TagType::UnsignedRational) |
+                        Ok(rexiv2::TagType::SignedRational) => {
+                            if let Some(value) = meta.get_tag_rational(&tag) {
+                                let value_str = format!("{}/{}", value.numer(), value.denom());
+                                xmp.set_property(xmp_prop.0, xmp_prop.1, &value_str, exempi::PROP_NONE);
                             }
+                        },
+                        Ok(rexiv2::TagType::Comment) => {
+                            if let Ok(value) = meta.get_tag_string(&tag) {
+                                xmp.set_property(xmp_prop.0, xmp_prop.1, &value, exempi::PROP_NONE);
+                            }
+                        },
+                        _ => {
+                            err_out!("Unhandled type {:?} for {}", tagtype, &tag);
                         }
-                    },
-                    Ok(rexiv2::TagType::UnsignedRational) |
-                    Ok(rexiv2::TagType::SignedRational) => {
-                        if let Some(value) = meta.get_tag_rational(&tag) {
-                            let value_str = format!("{}/{}", value.numer(), value.denom());
-                            xmp.set_property(xmp_prop.0, xmp_prop.1, &value_str, exempi::PROP_NONE);
-                        }
-                    },
-                    Ok(rexiv2::TagType::Comment) => {
-                        if let Ok(value) = meta.get_tag_string(&tag) {
-                            xmp.set_property(xmp_prop.0, xmp_prop.1, &value, exempi::PROP_NONE);
-                        }
-                    },
-                    _ => {
-                        err_out!("Unhandled type {:?} for {}", tagtype, &tag);
                     }
                 }
             } else {
diff --git a/src/lib.rs b/src/lib.rs
index 77e5ed1..0638867 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -29,6 +29,7 @@ extern crate gtk_sys;
 #[macro_use]
 extern crate lazy_static;
 extern crate libc;
+extern crate multimap;
 extern crate rexiv2;
 extern crate rusqlite;
 #[macro_use]


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