diff options
| author | Gabriel Schneider <[email protected]> | 2026-07-02 21:41:13 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-01 15:02:07 -0300 |
| commit | 81992cc92743a98066ee1a9025bc74f91cf0e967 (patch) | |
| tree | 12c07f68f8ad030f6c6f8a2b3415998d0a87eee7 /image.zig | |
| parent | bead9f0b78380d1428f40fdab339c1c8f88fa626 (diff) | |
| download | pardes-81992cc92743a98066ee1a9025bc74f91cf0e967.tar.gz pardes-81992cc92743a98066ee1a9025bc74f91cf0e967.zip | |
storage and replay
Diffstat (limited to 'image.zig')
| -rw-r--r-- | image.zig | 39 |
1 files changed, 26 insertions, 13 deletions
@@ -78,7 +78,8 @@ pub fn deinitView(view: *View, gpa: std.mem.Allocator) void { pub fn isImagePath(path: []const u8) bool { const exts = [_][]const u8{ ".png", ".jpg", ".jpeg", ".jpe", ".bmp", ".tga", - ".gif", ".psd", ".hdr", ".pic", ".pnm", ".ppm", ".pgm", + ".gif", ".psd", ".hdr", ".pic", ".pnm", ".ppm", + ".pgm", }; for (exts) |ext| { if (path.len >= ext.len and std.ascii.eqlIgnoreCase(path[path.len - ext.len ..], ext)) return true; @@ -86,17 +87,7 @@ pub fn isImagePath(path: []const u8) bool { return false; } -// Decode (RGBA), downscale to MAX_DIM, keep the pixels for PETSCII, and — when the -// terminal supports kitty graphics — transmit them once. Runs from the render loop, -// which owns the tty writer. On failure `handle` stays null (PETSCII still works). -pub fn ensureLoaded(view: *View, vx: *vaxis.Vaxis, gpa: std.mem.Allocator, writer: *std.Io.Writer) void { - if (view.tried) return; - view.tried = true; - var pathbuf: [4096]u8 = undefined; - const pz = std.fmt.bufPrintZ(&pathbuf, "{s}", .{view.path}) catch return; - var img = zstbi.Image.loadFromFile(pz, 4) catch return; // force 4 components = RGBA - defer img.deinit(); - +fn keepDecodedImage(view: *View, vx: *vaxis.Vaxis, gpa: std.mem.Allocator, writer: *std.Io.Writer, img: *const zstbi.Image) void { // downscale the longest side to MAX_DIM (keeping aspect) when it's bigger. var scaled: ?zstbi.Image = null; defer if (scaled) |*s| s.deinit(); @@ -106,7 +97,7 @@ pub fn ensureLoaded(view: *View, vx: *vaxis.Vaxis, gpa: std.mem.Allocator, write const nh = @max(1, img.height * MAX_DIM / longest); scaled = img.resize(nw, nh); break :blk &scaled.?; - } else &img; + } else img; // keep a gpa-owned copy of the pixels for the PETSCII renderer. view.rgba = gpa.dupe(u8, src.data) catch &.{}; @@ -123,6 +114,28 @@ pub fn ensureLoaded(view: *View, vx: *vaxis.Vaxis, gpa: std.mem.Allocator, write view.handle = vx.transmitPreEncodedImage(writer, b64, @intCast(src.width), @intCast(src.height), .rgba) catch null; } +// Decode (RGBA), downscale to MAX_DIM, keep the pixels for PETSCII, and — when the +// terminal supports kitty graphics — transmit them once. Runs from the render loop, +// which owns the tty writer. On failure `handle` stays null (PETSCII still works). +pub fn ensureLoaded(view: *View, vx: *vaxis.Vaxis, gpa: std.mem.Allocator, writer: *std.Io.Writer) void { + if (view.tried) return; + view.tried = true; + var pathbuf: [4096]u8 = undefined; + const pz = std.fmt.bufPrintZ(&pathbuf, "{s}", .{view.path}) catch return; + var img = zstbi.Image.loadFromFile(pz, 4) catch return; // force 4 components = RGBA + defer img.deinit(); + keepDecodedImage(view, vx, gpa, writer, &img); +} + +pub fn ensureLoadedFromMemory(view: *View, bytes: []const u8, vx: *vaxis.Vaxis, gpa: std.mem.Allocator, writer: *std.Io.Writer) void { + if (view.tried) return; + view.tried = true; + if (bytes.len == 0) return; + var img = zstbi.Image.loadFromMemory(bytes, 4) catch return; // force 4 components = RGBA + defer img.deinit(); + keepDecodedImage(view, vx, gpa, writer, &img); +} + // (Re)build the cached PETSCII grid for the current body size, if PETSCII drawing // is active and the size changed. Runs from the render loop (which has gpa). pub fn ensureGrid(view: *View, gpa: std.mem.Allocator, body_cols: u16, body_rows: u16) void { |
