Skip to content

Commit

Permalink
image: add transmitPreEncodedImage method
Browse files Browse the repository at this point in the history
Add a method that allows users of the library to pre-encode an image
using whichever base64 encoder they want (ie a simd encoder).
  • Loading branch information
rockorager committed Jul 20, 2024
1 parent 22fab6f commit 81a6b37
Showing 1 changed file with 50 additions and 38 deletions.
88 changes: 50 additions & 38 deletions src/Vaxis.zig
Original file line number Diff line number Diff line change
Expand Up @@ -717,38 +717,16 @@ pub fn translateMouse(self: Vaxis, mouse: Mouse) Mouse {
return result;
}

pub fn transmitImage(
/// Transmit an image which has been pre-base64 encoded
pub fn transmitPreEncodedImage(
self: *Vaxis,
alloc: std.mem.Allocator,
tty: AnyWriter,
img: *zigimg.Image,
bytes: []const u8,
width: usize,
height: usize,
format: Image.TransmitFormat,
) !Image {
if (!self.caps.kitty_graphics) return error.NoGraphicsCapability;
defer self.next_img_id += 1;

var arena = std.heap.ArenaAllocator.init(alloc);
defer arena.deinit();

const buf = switch (format) {
.png => png: {
const png_buf = try arena.allocator().alloc(u8, img.imageByteSize());
const png = try img.writeToMemory(png_buf, .{ .png = .{} });
break :png png;
},
.rgb => rgb: {
try img.convert(.rgb24);
break :rgb img.rawBytes();
},
.rgba => rgba: {
try img.convert(.rgba32);
break :rgba img.rawBytes();
},
};

const b64_buf = try arena.allocator().alloc(u8, base64Encoder.calcSize(buf.len));
const encoded = base64Encoder.encode(b64_buf, buf);

const id = self.next_img_id;

const fmt: u8 = switch (format) {
Expand All @@ -757,41 +735,75 @@ pub fn transmitImage(
.png => 100,
};

if (encoded.len < 4096) {
if (bytes.len < 4096) {
try tty.print(
"\x1b_Gf={d},s={d},v={d},i={d};{s}\x1b\\",
.{
fmt,
img.width,
img.height,
width,
height,
id,
encoded,
bytes,
},
);
} else {
var n: usize = 4096;

try tty.print(
"\x1b_Gf={d},s={d},v={d},i={d},m=1;{s}\x1b\\",
.{ fmt, img.width, img.height, id, encoded[0..n] },
.{ fmt, width, height, id, bytes[0..n] },
);
while (n < encoded.len) : (n += 4096) {
const end: usize = @min(n + 4096, encoded.len);
const m: u2 = if (end == encoded.len) 0 else 1;
while (n < bytes.len) : (n += 4096) {
const end: usize = @min(n + 4096, bytes.len);
const m: u2 = if (end == bytes.len) 0 else 1;
try tty.print(
"\x1b_Gm={d};{s}\x1b\\",
.{
m,
encoded[n..end],
bytes[n..end],
},
);
}
}
return .{
.id = id,
.width = img.width,
.height = img.height,
.width = width,
.height = height,
};
}

pub fn transmitImage(
self: *Vaxis,
alloc: std.mem.Allocator,
tty: AnyWriter,
img: *zigimg.Image,
format: Image.TransmitFormat,
) !Image {
if (!self.caps.kitty_graphics) return error.NoGraphicsCapability;

var arena = std.heap.ArenaAllocator.init(alloc);
defer arena.deinit();

const buf = switch (format) {
.png => png: {
const png_buf = try arena.allocator().alloc(u8, img.imageByteSize());
const png = try img.writeToMemory(png_buf, .{ .png = .{} });
break :png png;
},
.rgb => rgb: {
try img.convert(.rgb24);
break :rgb img.rawBytes();
},
.rgba => rgba: {
try img.convert(.rgba32);
break :rgba img.rawBytes();
},
};

const b64_buf = try arena.allocator().alloc(u8, base64Encoder.calcSize(buf.len));
const encoded = base64Encoder.encode(b64_buf, buf);

return self.transmitPreEncodedImage(tty, encoded, img.width, img.height, format);
}

pub fn loadImage(
Expand Down

0 comments on commit 81a6b37

Please sign in to comment.