// SPDX-FileCopyrightText: © 2026 Jeffrey C. Ollie // SPDX-License-Identifier: MIT //! A decoded sixel image: its pixels, and what the stream said about them. const std = @import("std"); const z2d = @import("z2d"); const introducer = @import("introducer.zig"); const Image = @This(); /// How a sixel image ended. pub const Termination = enum { /// With the string terminator, `ESC \` or `0x9C`, as it should. st, /// With CAN or SUB, which abandon a control string. A terminal shows /// what had been drawn before them, and so does this. aborted, /// With some other escape sequence or C1 control, which a terminal takes /// as the end of the string before acting on it. interrupted, /// The input ran out first. end_of_data, }; /// The pixels, as an RGBA surface of exactly the image's size. The image /// owns it; `deinit` frees it. /// /// Every pixel is either opaque or fully transparent, since sixel has /// nothing in between. A pixel is transparent only when the introducer /// asked for an unfilled background (`P2 = 1`) and nothing drew on it. surface: z2d.Surface, /// The pixel aspect ratio the stream asked for, which is reported rather /// than applied: the surface has one pixel per sixel pixel. aspect: introducer.Aspect, /// Whether pixels the stream never drew were left transparent (`P2 = 1`) /// rather than filled with the color in register 0. transparent: bool, termination: Termination, /// Whether some of what the stream drew fell outside `Limits` and was /// dropped. clipped: bool, pub fn width(self: Image) u32 { return @intCast(self.surface.getWidth()); } pub fn height(self: Image) u32 { return @intCast(self.surface.getHeight()); } pub fn deinit(self: *Image, gpa: std.mem.Allocator) void { self.surface.deinit(gpa); self.* = undefined; }