summaryrefslogtreecommitdiff
path: root/src/metadata
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff.email>2023-06-14 20:36:37 +0200
committerJörg Frings-Fürst <debian@jff.email>2023-06-14 20:36:37 +0200
commitbb80d3feebdc9acc52e3f4ad24084d8425f043a2 (patch)
tree2084a84c39f159c6aea254775dc0880d52579d45 /src/metadata
parentb26ff0798252a1a8072dd2c7a67f6205de9fde11 (diff)
parent31804433d72460cbe0a39f9f8ea5e76058d84cda (diff)
Merge branch 'feature/upstream' into develop
Diffstat (limited to 'src/metadata')
-rw-r--r--src/metadata/MediaMetadata.vala15
-rw-r--r--src/metadata/MetadataDateTime.vala78
-rw-r--r--src/metadata/MetadataRational.vala26
-rw-r--r--src/metadata/meson.build16
4 files changed, 135 insertions, 0 deletions
diff --git a/src/metadata/MediaMetadata.vala b/src/metadata/MediaMetadata.vala
new file mode 100644
index 0000000..a329cb1
--- /dev/null
+++ b/src/metadata/MediaMetadata.vala
@@ -0,0 +1,15 @@
+/* Copyright 2016 Software Freedom Conservancy Inc.
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+public abstract class MediaMetadata {
+ public abstract void read_from_file(File file) throws Error;
+
+ public abstract MetadataDateTime? get_creation_date_time();
+
+ public abstract string? get_title();
+
+ public abstract string? get_comment();
+}
diff --git a/src/metadata/MetadataDateTime.vala b/src/metadata/MetadataDateTime.vala
new file mode 100644
index 0000000..9dae99b
--- /dev/null
+++ b/src/metadata/MetadataDateTime.vala
@@ -0,0 +1,78 @@
+public errordomain MetadataDateTimeError {
+ INVALID_FORMAT,
+ UNSUPPORTED_FORMAT
+}
+
+public class MetadataDateTime {
+
+ private DateTime timestamp;
+
+ public MetadataDateTime(DateTime timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public MetadataDateTime.from_exif(string label) throws MetadataDateTimeError {
+ if (!from_exif_date_time(label, out timestamp))
+ throw new MetadataDateTimeError.INVALID_FORMAT("%s is not EXIF format date/time", label);
+ }
+
+ public MetadataDateTime.from_iptc(string date, string time) throws MetadataDateTimeError {
+ // TODO: Support IPTC date/time format
+ throw new MetadataDateTimeError.UNSUPPORTED_FORMAT("IPTC date/time format not currently supported");
+ }
+
+ public MetadataDateTime.from_xmp(string label) throws MetadataDateTimeError {
+ var dt = new DateTime.from_iso8601(label, null);
+ if (dt == null)
+ throw new MetadataDateTimeError.INVALID_FORMAT("%s is not XMP format date/time", label);
+
+ timestamp = dt;
+ }
+
+ public DateTime? get_timestamp() {
+ return timestamp;
+ }
+
+ public string get_exif_label() {
+ return to_exif_date_time(timestamp);
+ }
+
+ // TODO: get_iptc_date() and get_iptc_time()
+
+ public string get_xmp_label() {
+ return timestamp.format_iso8601();
+ }
+
+ public static bool from_exif_date_time(string date_time, out DateTime? timestamp) {
+ timestamp = null;
+
+ Time tm = Time();
+
+ // Check standard EXIF format
+ if (date_time.scanf("%d:%d:%d %d:%d:%d",
+ &tm.year, &tm.month, &tm.day, &tm.hour, &tm.minute, &tm.second) != 6) {
+ // Fallback in a more generic format
+ string tmp = date_time.dup();
+ tmp.canon("0123456789", ' ');
+ if (tmp.scanf("%4d%2d%2d%2d%2d%2d",
+ &tm.year, &tm.month, &tm.day, &tm.hour, &tm.minute,&tm.second) != 6)
+ return false;
+ }
+
+ // watch for bogosity
+ if (tm.year <= 1900 || tm.month <= 0 || tm.day < 0 || tm.hour < 0 || tm.minute < 0 || tm.second < 0)
+ return false;
+
+ timestamp = new DateTime.local(tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
+
+ return true;
+ }
+
+ public static string to_exif_date_time(DateTime timestamp) {
+ return timestamp.to_local().format("%Y:%m:%d %H:%M:%S");
+ }
+
+ public string to_string() {
+ return to_exif_date_time(timestamp);
+ }
+}
diff --git a/src/metadata/MetadataRational.vala b/src/metadata/MetadataRational.vala
new file mode 100644
index 0000000..ec3ac17
--- /dev/null
+++ b/src/metadata/MetadataRational.vala
@@ -0,0 +1,26 @@
+public struct MetadataRational {
+ public int numerator;
+ public int denominator;
+
+ public MetadataRational.invalid() {
+ this.numerator = -1;
+ this.denominator = -1;
+ }
+
+ public MetadataRational(int numerator, int denominator) {
+ this.numerator = numerator;
+ this.denominator = denominator;
+ }
+
+ private bool is_component_valid(int component) {
+ return (component >= 0) && (component <= 1000000);
+ }
+
+ public bool is_valid() {
+ return (is_component_valid(numerator) && is_component_valid(denominator));
+ }
+
+ public string to_string() {
+ return (is_valid()) ? ("%d/%d".printf(numerator, denominator)) : "";
+ }
+}
diff --git a/src/metadata/meson.build b/src/metadata/meson.build
new file mode 100644
index 0000000..7f322ca
--- /dev/null
+++ b/src/metadata/meson.build
@@ -0,0 +1,16 @@
+libmetadata = static_library(
+ 'metadata',
+ [
+ 'MediaMetadata.vala',
+ 'MetadataDateTime.vala',
+ 'MetadataRational.vala'
+ ],
+ dependencies : [
+ gio
+ ]
+)
+
+metadata = declare_dependency(
+ include_directories : include_directories('.'),
+ link_with : libmetadata
+)