aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/pkg/wuffs/src
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-10 21:51:57 +0300
committerGitHub <noreply@github.com>2026-09-10 21:51:57 +0300
commit425c86179791cd32e2d4ce0ae7f269940b4b0663 (patch)
treee52c4383a6d69216cbe2a32638bf90841d7e2189 /vendor/libghostty-vt/pkg/wuffs/src
parent90e947a6e26e02f10ec7f1694c4eb5b78a86406b (diff)
chore: upgrade libghostty and preserve terminal behavior (#3906)
Diffstat (limited to 'vendor/libghostty-vt/pkg/wuffs/src')
-rw-r--r--vendor/libghostty-vt/pkg/wuffs/src/c.zig18
-rw-r--r--vendor/libghostty-vt/pkg/wuffs/src/error.zig2
-rw-r--r--vendor/libghostty-vt/pkg/wuffs/src/jpeg.zig2
-rw-r--r--vendor/libghostty-vt/pkg/wuffs/src/main.zig48
-rw-r--r--vendor/libghostty-vt/pkg/wuffs/src/png.zig2
-rw-r--r--vendor/libghostty-vt/pkg/wuffs/src/swizzle.zig73
6 files changed, 120 insertions, 25 deletions
diff --git a/vendor/libghostty-vt/pkg/wuffs/src/c.zig b/vendor/libghostty-vt/pkg/wuffs/src/c.zig
deleted file mode 100644
index d94247df..00000000
--- a/vendor/libghostty-vt/pkg/wuffs/src/c.zig
+++ /dev/null
@@ -1,18 +0,0 @@
-pub const c = @cImport({
- for (defines) |d| @cDefine(d, "1");
- @cInclude("wuffs-v0.4.c");
-});
-
-/// All the C macros defined so that the header matches the build.
-pub const defines: []const []const u8 = &[_][]const u8{
- "WUFFS_CONFIG__MODULES",
- "WUFFS_CONFIG__MODULE__AUX__BASE",
- "WUFFS_CONFIG__MODULE__AUX__IMAGE",
- "WUFFS_CONFIG__MODULE__BASE",
- "WUFFS_CONFIG__MODULE__ADLER32",
- "WUFFS_CONFIG__MODULE__CRC32",
- "WUFFS_CONFIG__MODULE__DEFLATE",
- "WUFFS_CONFIG__MODULE__JPEG",
- "WUFFS_CONFIG__MODULE__PNG",
- "WUFFS_CONFIG__MODULE__ZLIB",
-};
diff --git a/vendor/libghostty-vt/pkg/wuffs/src/error.zig b/vendor/libghostty-vt/pkg/wuffs/src/error.zig
index 0be55cf4..e4ca5c1d 100644
--- a/vendor/libghostty-vt/pkg/wuffs/src/error.zig
+++ b/vendor/libghostty-vt/pkg/wuffs/src/error.zig
@@ -1,6 +1,6 @@
const std = @import("std");
-const c = @import("c.zig").c;
+const c = @import("wuffs_c");
pub const Error = std.mem.Allocator.Error || error{ WuffsError, Overflow };
diff --git a/vendor/libghostty-vt/pkg/wuffs/src/jpeg.zig b/vendor/libghostty-vt/pkg/wuffs/src/jpeg.zig
index 69d91c8a..a7bc4bdd 100644
--- a/vendor/libghostty-vt/pkg/wuffs/src/jpeg.zig
+++ b/vendor/libghostty-vt/pkg/wuffs/src/jpeg.zig
@@ -1,6 +1,6 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
-const c = @import("c.zig").c;
+const c = @import("wuffs_c");
const Error = @import("error.zig").Error;
const check = @import("error.zig").check;
const ImageData = @import("main.zig").ImageData;
diff --git a/vendor/libghostty-vt/pkg/wuffs/src/main.zig b/vendor/libghostty-vt/pkg/wuffs/src/main.zig
index 207d83f9..41b74cab 100644
--- a/vendor/libghostty-vt/pkg/wuffs/src/main.zig
+++ b/vendor/libghostty-vt/pkg/wuffs/src/main.zig
@@ -1,3 +1,4 @@
+const builtin = @import("builtin");
const std = @import("std");
pub const png = @import("png.zig");
@@ -15,6 +16,51 @@ pub const ImageData = struct {
data: []u8,
};
+// Wuffs' generated `wuffs_foo__bar__alloc()` convenience functions are the
+// only code that references libc's calloc/free. We never call them
+// and linker garbage collection strips them, but that isn't guaranteed.
+// Freestanding consumers may have no allocator to resolve these symbols.
+// Never export stubs for hosted targets: hidden weak symbols in a static
+// archive can override the embedding executable's dynamically linked libc.
+comptime {
+ if (!builtin.link_libc and builtin.os.tag == .freestanding) {
+ @export(&callocStub, .{
+ .name = "calloc",
+ .linkage = .weak,
+ .visibility = .hidden,
+ });
+ @export(&freeStub, .{
+ .name = "free",
+ .linkage = .weak,
+ .visibility = .hidden,
+ });
+ }
+}
+
+fn callocStub(count: usize, size: usize) callconv(.c) ?*anyopaque {
+ _ = count;
+ _ = size;
+ return null;
+}
+
+fn freeStub(ptr: ?*anyopaque) callconv(.c) void {
+ _ = ptr;
+}
+
test {
- std.testing.refAllDeclsRecursive(@This());
+ refAllDeclsRecursive(@This());
+}
+
+/// Copied from 0.15.2 stdlib (MIT license).
+fn refAllDeclsRecursive(comptime T: type) void {
+ if (!builtin.is_test) return;
+ inline for (comptime std.meta.declarations(T)) |decl| {
+ if (@TypeOf(@field(T, decl.name)) == type) {
+ switch (@typeInfo(@field(T, decl.name))) {
+ .@"struct", .@"enum", .@"union", .@"opaque" => refAllDeclsRecursive(@field(T, decl.name)),
+ else => {},
+ }
+ }
+ _ = &@field(T, decl.name);
+ }
}
diff --git a/vendor/libghostty-vt/pkg/wuffs/src/png.zig b/vendor/libghostty-vt/pkg/wuffs/src/png.zig
index 57a0e63b..4bf3d759 100644
--- a/vendor/libghostty-vt/pkg/wuffs/src/png.zig
+++ b/vendor/libghostty-vt/pkg/wuffs/src/png.zig
@@ -1,6 +1,6 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
-const c = @import("c.zig").c;
+const c = @import("wuffs_c");
const Error = @import("error.zig").Error;
const check = @import("error.zig").check;
const ImageData = @import("main.zig").ImageData;
diff --git a/vendor/libghostty-vt/pkg/wuffs/src/swizzle.zig b/vendor/libghostty-vt/pkg/wuffs/src/swizzle.zig
index 352cf2b5..d873efea 100644
--- a/vendor/libghostty-vt/pkg/wuffs/src/swizzle.zig
+++ b/vendor/libghostty-vt/pkg/wuffs/src/swizzle.zig
@@ -1,7 +1,7 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const assert = std.debug.assert;
-const c = @import("c.zig").c;
+const c = @import("wuffs_c");
const Error = @import("error.zig").Error;
const log = std.log.scoped(.wuffs_swizzler);
@@ -16,11 +16,15 @@ pub fn gToRgba(alloc: Allocator, src: []const u8) Error![]u8 {
}
pub fn gaToRgba(alloc: Allocator, src: []const u8) Error![]u8 {
+ // Wuffs doesn't support YA_PREMUL as a swizzle source. The nonpremul
+ // pair produces the same bytes (r=g=b=y, a=a, no alpha math), which
+ // is what we want: alpha semantics are preserved as-is, matching the
+ // other conversions here.
return swizzle(
alloc,
src,
- c.WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL,
- c.WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL,
+ c.WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL,
+ c.WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL,
);
}
@@ -51,6 +55,69 @@ pub fn bgraToRgba(alloc: Allocator, src: []const u8) Error![]u8 {
);
}
+/// Composite `src` over `dst` in place. Both are straight
+/// (non-premultiplied) alpha RGBA of the same length. A transparent
+/// destination pixel takes the source pixel exactly; wuffs composites
+/// everything else in 16-bit integer space.
+pub fn rgbaSrcOver(dst: []u8, src: []const u8) void {
+ assert(dst.len == src.len);
+ assert(dst.len % 4 == 0);
+
+ var swizzler: c.wuffs_base__pixel_swizzler = undefined;
+ const status = c.wuffs_base__pixel_swizzler__prepare(
+ &swizzler,
+ c.wuffs_base__make_pixel_format(c.WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL),
+ c.wuffs_base__empty_slice_u8(),
+ c.wuffs_base__make_pixel_format(c.WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL),
+ c.wuffs_base__empty_slice_u8(),
+ c.WUFFS_BASE__PIXEL_BLEND__SRC_OVER,
+ );
+ // This format pair and blend mode is a supported swizzle, so
+ // preparation can only fail on a programming error.
+ assert(c.wuffs_base__status__is_ok(&status));
+
+ _ = c.wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
+ &swizzler,
+ c.wuffs_base__make_slice_u8(dst.ptr, dst.len),
+ c.wuffs_base__empty_slice_u8(),
+ c.wuffs_base__make_slice_u8(@constCast(src.ptr), src.len),
+ );
+}
+
+test "gaToRgba" {
+ const rgba = try gaToRgba(std.testing.allocator, &.{ 7, 100, 8, 200 });
+ defer std.testing.allocator.free(rgba);
+
+ try std.testing.expectEqualSlices(u8, &.{
+ 7, 7, 7, 100,
+ 8, 8, 8, 200,
+ }, rgba);
+}
+
+test "rgbaSrcOver" {
+ // 50% white over opaque black, opaque over anything, transparent
+ // source over anything, and anything over a transparent
+ // destination (exact source passthrough).
+ var dst = [_]u8{
+ 0, 0, 0, 255,
+ 10, 20, 30, 40,
+ 10, 20, 30, 40,
+ 0, 0, 0, 0,
+ };
+ rgbaSrcOver(&dst, &.{
+ 255, 255, 255, 128,
+ 100, 110, 120, 255,
+ 100, 110, 120, 0,
+ 200, 100, 50, 128,
+ });
+ try std.testing.expectEqualSlices(u8, &.{
+ 128, 128, 128, 255,
+ 100, 110, 120, 255,
+ 10, 20, 30, 40,
+ 200, 100, 50, 128,
+ }, &dst);
+}
+
fn swizzle(
alloc: Allocator,
src: []const u8,