aboutsummaryrefslogtreecommitdiff
path: root/src/storage/image-manager/exif.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/storage/image-manager/exif.zig')
-rw-r--r--src/storage/image-manager/exif.zig54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/storage/image-manager/exif.zig b/src/storage/image-manager/exif.zig
new file mode 100644
index 0000000..02199cf
--- /dev/null
+++ b/src/storage/image-manager/exif.zig
@@ -0,0 +1,54 @@
+const std = @import("std");
+const exif = @cImport(@cInclude("libexif/exif-data.h"));
+const cstd = @cImport(@cInclude("time.h"));
+
+const tags = [_]c_uint {
+ exif.EXIF_TAG_DATE_TIME,
+ exif.EXIF_TAG_DATE_TIME_ORIGINAL,
+ exif.EXIF_TAG_DATE_TIME_DIGITIZED,
+};
+
+pub fn get_date_time(path: [*:0]const u8) ?i64 {
+ const exif_data = exif.exif_data_new_from_file(path);
+ defer exif.exif_data_unref(exif_data);
+
+ if (exif_data == null) {
+ return null;
+ }
+
+ var entry: ?[*c]exif.struct__ExifEntry = null;
+ for (0..exif.EXIF_IFD_COUNT) |index| {
+ for (tags) |tag| {
+ entry = exif.exif_content_get_entry((exif_data.*).ifd[index], tag);
+
+ if (entry) |_| { break; }
+ }
+
+ if (entry) |_| { break; }
+ }
+
+ if (entry == null) {
+ return null;
+ }
+
+ const c_data = (entry.?.*).data;
+
+ return parse_date(c_data);
+}
+
+extern fn strptime(
+ s: [*c]const u8,
+ format: [*c]const u8,
+ tm: *cstd.tm,
+) ?*const u8;
+
+extern fn timegm(tm: *cstd.tm) i64;
+
+fn parse_date(date: [*:0]const u8) ?i64 {
+ var tm: cstd.tm = std.mem.zeroes(cstd.tm);
+ if (strptime(date, "%Y:%m:%d %H:%M:%S", &tm)) |_| {
+ return timegm(&tm);
+ }
+
+ return null;
+}