+9
-3
build.zig.zon
+9
-3
build.zig.zon
···
2
2
.name = .jido,
3
3
.fingerprint = 0xee45eabe36cafb57,
4
4
.version = "1.3.0",
5
-
.minimum_zig_version = "0.14.0",
5
+
.minimum_zig_version = "0.15.2",
6
6
7
7
.dependencies = .{
8
+
// Replace with rockorager/libvaxis once https://github.com/rockorager/libvaxis/pull/293 is merged
8
9
.vaxis = .{
9
-
.url = "git+https://github.com/rockorager/libvaxis.git#75035b169e91a51c233f3742161f8eb8eafca659",
10
-
.hash = "vaxis-0.5.1-BWNV_IE-CQBYmSf_boEKUyv6den0Gmj5LksxvdCx2pBL",
10
+
.url = "git+https://github.com/rob9315/libvaxis.git#8d04cffd9137b4a8c56b356de98b32023ae752f3",
11
+
.hash = "vaxis-0.5.1-BWNV_OA-CQDeFBHIx9ryyASogr2GE3FsAm-l5Ii5-HZT",
11
12
},
12
13
.fuzzig = .{
13
14
.url = "git+https://github.com/fjebaker/fuzzig#4251fe4230d38e721514394a485db62ee1667ff3",
···
21
22
.zuid = .{
22
23
.url = "https://github.com/BrookJeynes/zuid/archive/refs/heads/bj/2025-12-31/feat/0.15.1.tar.gz",
23
24
.hash = "zuid-3.0.0-l7aPyUlXAAAk9BLSDm2roA3i78Sy6_GvQI4hwe0PHI_m",
25
+
},
26
+
// Replace with zigimg/zigimg once https://github.com/zigimg/zigimg/pull/305 is merged
27
+
.zigimg = .{
28
+
.url = "git+https://github.com/brookjeynes/zigimg.git#9714df09f76891323c7fdbbbf23a17b79024fffb",
29
+
.hash = "zigimg-0.1.0-8_eo2j4mFwCU7tWnqvkYtzqe-OPRn_bxEql_IJhW85LT",
24
30
},
25
31
},
26
32
+7
-2
src/app.zig
+7
-2
src/app.zig
···
79
79
};
80
80
81
81
pub const Image = struct {
82
+
const buf_size = (1024 * 1024) * 5; // 5mb
82
83
const Status = enum {
83
84
ready,
84
85
processing,
86
+
failed,
85
87
};
86
88
87
89
///Only use on first transmission. Subsequent draws should use
···
91
93
path: ?[]const u8 = null,
92
94
status: Status = .processing,
93
95
94
-
pub fn deinit(self: @This(), alloc: std.mem.Allocator) void {
96
+
pub fn deinit(self: @This(), alloc: std.mem.Allocator, vx: vaxis.Vaxis, tty: *vaxis.Tty) void {
97
+
if (self.image) |image| {
98
+
vx.freeImage(tty.writer(), image.id);
99
+
}
95
100
if (self.data) |data| {
96
101
var d = data;
97
102
d.deinit(alloc);
···
197
202
198
203
var image_iter = self.images.cache.iterator();
199
204
while (image_iter.next()) |img| {
200
-
img.value_ptr.deinit(self.alloc);
205
+
img.value_ptr.deinit(self.alloc, self.vx, &self.tty);
201
206
}
202
207
self.images.cache.deinit();
203
208
}
+54
-12
src/drawer.zig
+54
-12
src/drawer.zig
···
208
208
break :file;
209
209
}
210
210
211
+
if (cache_entry.status == .failed) {
212
+
_ = preview_win.print(&.{
213
+
.{ .text = "Failed to process image." },
214
+
}, .{});
215
+
break :file;
216
+
}
217
+
211
218
if (cache_entry.image) |img| {
212
219
img.draw(preview_win, .{ .scale = .contain }) catch |err| {
213
220
const message = try std.fmt.allocPrint(app.alloc, "Failed to draw image to screen - {}.", .{err});
···
224
231
} else {
225
232
if (cache_entry.data == null) {
226
233
const path = try app.alloc.dupe(u8, self.current_item_path);
227
-
var buffer: [1024]u8 = undefined;
228
-
processImage(app, path, &buffer) catch break :unsupported;
234
+
processImage(app, path) catch {
235
+
app.alloc.free(path);
236
+
break :unsupported;
237
+
};
238
+
_ = preview_win.print(&.{
239
+
.{ .text = "Image still processing." },
240
+
}, .{});
241
+
break :file;
229
242
}
230
243
231
244
if (app.vx.transmitImage(app.alloc, app.tty.writer(), &cache_entry.data.?, .rgba)) |img| {
···
241
254
break :file;
242
255
};
243
256
cache_entry.image = img;
244
-
cache_entry.data.?.deinit(app.alloc);
257
+
if (cache_entry.data) |data| {
258
+
var d = data;
259
+
d.deinit(app.alloc);
260
+
}
245
261
cache_entry.data = null;
246
262
} else |_| {
247
263
break :unsupported;
···
250
266
251
267
break :file;
252
268
} else {
269
+
_ = preview_win.print(&.{
270
+
.{ .text = "Processing image." },
271
+
}, .{});
272
+
253
273
const path = try app.alloc.dupe(u8, self.current_item_path);
254
-
var buffer: [1024]u8 = undefined;
255
-
processImage(app, path, &buffer) catch break :unsupported;
274
+
processImage(app, path) catch {
275
+
app.alloc.free(path);
276
+
break :unsupported;
277
+
};
256
278
}
257
279
258
280
break :file;
···
630
652
}, .{ .wrap = .word });
631
653
}
632
654
633
-
fn processImage(app: *App, path: []const u8, buffer: *[1024]u8) error{ Unsupported, OutOfMemory }!void {
655
+
fn processImage(app: *App, path: []const u8) error{ Unsupported, OutOfMemory }!void {
634
656
app.images.cache.put(path, .{ .path = path, .status = .processing }) catch {
635
657
const message = try std.fmt.allocPrint(app.alloc, "Failed to load image '{s}' - error occurred while attempting to add image to cache.", .{path});
636
658
defer app.alloc.free(message);
···
642
664
const load_img_thread = std.Thread.spawn(.{}, loadImage, .{
643
665
app,
644
666
path,
645
-
buffer,
646
-
}) catch return error.Unsupported;
667
+
}) catch {
668
+
app.images.mutex.lock();
669
+
if (app.images.cache.getPtr(path)) |entry| {
670
+
entry.status = .failed;
671
+
}
672
+
app.images.mutex.unlock();
673
+
674
+
const message = try std.fmt.allocPrint(app.alloc, "Failed to load image '{s}' - error occurred while attempting to spawn processing thread.", .{path});
675
+
defer app.alloc.free(message);
676
+
app.notification.write(message, .err) catch {};
677
+
if (app.file_logger) |file_logger| file_logger.write(message, .err) catch {};
678
+
679
+
return error.Unsupported;
680
+
};
647
681
load_img_thread.detach();
648
682
}
649
683
650
-
fn loadImage(app: *App, path: []const u8, buffer: *[1024]u8) error{ Unsupported, OutOfMemory }!void {
651
-
const data = vaxis.zigimg.Image.fromFilePath(app.alloc, path, buffer) catch {
684
+
fn loadImage(app: *App, path: []const u8) error{OutOfMemory}!void {
685
+
var buf: [(1024 * 1024) * 5]u8 = undefined;
686
+
const data = vaxis.zigimg.Image.fromFilePath(app.alloc, path, &buf) catch {
687
+
app.images.mutex.lock();
688
+
if (app.images.cache.getPtr(path)) |entry| {
689
+
entry.status = .failed;
690
+
}
691
+
app.images.mutex.unlock();
692
+
652
693
const message = try std.fmt.allocPrint(app.alloc, "Failed to load image '{s}' - error occurred while attempting to read image from path.", .{path});
653
694
defer app.alloc.free(message);
654
695
app.notification.write(message, .err) catch {};
655
696
if (app.file_logger) |file_logger| file_logger.write(message, .err) catch {};
656
-
return error.Unsupported;
697
+
698
+
return;
657
699
};
658
700
659
701
app.images.mutex.lock();
···
665
707
defer app.alloc.free(message);
666
708
app.notification.write(message, .err) catch {};
667
709
if (app.file_logger) |file_logger| file_logger.write(message, .err) catch {};
668
-
return error.Unsupported;
710
+
return;
669
711
}
670
712
app.images.mutex.unlock();
671
713