diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2025-11-19 09:15:49 +0100 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2025-11-19 09:15:49 +0100 |
| commit | 4c06eb64cbed3562e428ce59857d1763098638f3 (patch) | |
| tree | cc9c8164e76cd48e1dd4ef963329dcfa3c1b152f /src/storage/image-manager/exif.zig | |
| parent | 6201307fecf8398a1b53bf276bc08bfbb3524899 (diff) | |
allow images to upload and sort if according to their datetime
Diffstat (limited to 'src/storage/image-manager/exif.zig')
| -rw-r--r-- | src/storage/image-manager/exif.zig | 54 |
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; +} |