authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-10-11 22:40:57 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-10-11 22:40:57 -07:00
log1af3b0a4f587b3ae4c25fad867decc2fbcfdc4af
tree9eeb428809e3f65bbbfd442fb96ccddde473583c
parentc42f8f1d0eaa0f77ff46afd131b8f778b40552e4

add YCbCr -> sRGB conversion


2 files changed, 43 insertions(+), 0 deletions(-)

YCbCr.zig+15
......@@ -3,6 +3,7 @@
33const std = @import("std");
44const Self = @This();
55const color = @import("./mod.zig");
6const _x = @import("./_x.zig");
67
78y: u8,
89cb: u8,
......@@ -25,3 +26,17 @@ pub fn initYCbCr(y: u8, cb: u8, cr: u8) Self {
2526pub fn eql(x: Self, y: Self) bool {
2627 return x.y == y.y and x.cb == y.cb and x.cr == y.cr and x.a == y.a;
2728}
29
30pub usingnamespace _x.mixin(@This(), .y, .cb, .cr);
31
32pub fn to_srgb(x: Self) color.sRGB {
33 // zig fmt: off
34 const f = x.to_vec();
35 return color.sRGB.from_vec(.{
36 @max(0, @min(255, f[0] + 1.402 * (f[2]-128))),
37 @max(0, @min(255, f[0] - 0.34414 * (f[1]-128) - 0.71414 * (f[2]-128))),
38 @max(0, @min(255, f[0] + 1.772 * (f[1]-128))),
39 @max(0, @min(255, f[3])),
40 });
41 // zig fmt: on
42}
_x.zig created+28
......@@ -0,0 +1,28 @@
1const std = @import("std");
2
3pub fn mixin(
4 comptime T: type,
5 comptime f1: std.meta.FieldEnum(T),
6 comptime f2: std.meta.FieldEnum(T),
7 comptime f3: std.meta.FieldEnum(T),
8) type {
9 return struct {
10 pub fn to_vec(x: T) @Vector(4, f32) {
11 return .{
12 @floatFromInt(@field(x, @tagName(f1))),
13 @floatFromInt(@field(x, @tagName(f2))),
14 @floatFromInt(@field(x, @tagName(f3))),
15 @floatFromInt(x.a),
16 };
17 }
18
19 pub fn from_vec(in: @Vector(4, f32)) T {
20 var x: T = undefined;
21 @field(x, @tagName(f1)) = @intFromFloat(in[0]);
22 @field(x, @tagName(f2)) = @intFromFloat(in[1]);
23 @field(x, @tagName(f3)) = @intFromFloat(in[2]);
24 x.a = @intFromFloat(in[3]);
25 return x;
26 }
27 };
28}