feat(core): support file-backed RGBA images - #1328
Open
neriousy wants to merge 9 commits into
Open
Conversation
neriousy
marked this pull request as ready for review
August 4, 2026 08:17
neriousy
requested review from
Hona,
kommander,
msmps and
simonklee
as code owners
August 4, 2026 08:17
Member
|
The ownership model needs a look:
|
neriousy
marked this pull request as draft
August 6, 2026 07:56
Contributor
Author
|
Marking as draft for now, I asked |
neriousy
marked this pull request as ready for review
August 6, 2026 18:16
Contributor
Author
|
Okay, adjuted the PR a bit - most of the bullet points are done but
smth like this: fn fileHasTransparency(file: std.fs.File, byte_len: usize) !bool {
var buffer: [64 * 1024]u8 = undefined;
var offset: usize = 0;
while (offset < byte_len) {
const chunk = buffer[0..@min(buffer.len, byte_len - offset)];
const read = try file.preadAll(chunk, offset);
if (read != chunk.len) return error.MalformedInput;
var alpha: usize = 3;
while (alpha < chunk.len) : (alpha += 4) {
if (chunk[alpha] != 255) return true;
}
offset += chunk.len;
}
return false;
}idk if its worth it |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces
NativeImage.adoptRgbaFile(path, width, height)for lazy, file-backed RGBA8 images. After validating the file, OpenTUI owns it and materializes its pixels only when an operation or terminal protocol requires them.For eligible local Kitty terminals, OpenTUI emits an
f=32,t=ttransmit command so the terminal can read the unchanged frame file directly. All other cases use the existing inline-pixel path.This is a low-level
NativeImageAPI.ImageSource,ImageRenderable, and the renderer output lifecycle are unchanged.Motivation
Some image producers already publish complete frames as raw RGBA files. Loading those files through
NativeImage.fromRgba()requires reading every frame into a JavaScriptUint8Array, copying it into the native image, and then base64-encoding the pixels through stdout for Kitty.File adoption lets those frames participate in OpenTUI's normal image lifecycle—including placement, clipping, overlays, movement, resizing, and protocol fallback—without that extra work when the terminal can consume the file directly.
One intended consumer is
opentui-browser, whose browser sidecar produces bounded, top-down RGBA8 frame files.API contract
NativeImage.adoptRgbaFile(path, width, height)accepts a regular file whose size is exactlywidth * height * 4. The data must be tightly packed, top-down RGBA8.info()is cached and stable. File-backed images conservatively reporthasAlpha: truebecause answering it does not materialize the file.Kitty file transport
File transport is available only when:
tty-graphics-protocolWindows, remote terminals, custom or memory output, image feeds, transformed images, unqualified paths, and symlink escapes fall back to inline pixels.
Kitty takes responsibility for deleting a qualified
t=ttemporary file. OpenTUI marks the path transferred only after the complete transmit command has been serialized. A serialization error leaves the file owned and retryable. After a successful file transmission, subsequent transmissions use the retained descriptor and fall back to inline pixels.This ownership boundary is best-effort: a later frame write may still fail or be dropped after the command has been serialized. OpenTUI does not wait for terminal acknowledgement because Kitty responses are suppressed for these commands. Path qualification follows the Kitty graphics protocol.
Benchmark
A focused native benchmark compares the two 1280×720 paths:
t=tThe measurement includes image creation or adoption, Kitty serialization, and disposal. It excludes producer file creation, terminal-side file reads, and shared placement work.
Validation
bun run fmt:checkbun run lint