diff options
Diffstat (limited to 'src/metadata')
| -rw-r--r-- | src/metadata/MediaMetadata.vala | 15 | ||||
| -rw-r--r-- | src/metadata/MetadataDateTime.vala | 78 | ||||
| -rw-r--r-- | src/metadata/MetadataRational.vala | 26 | ||||
| -rw-r--r-- | src/metadata/meson.build | 16 | 
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 +)  | 
