Color Management (RGBA8)
Relevant source files
The following files were used as context for generating this wiki page:
The guiltty project utilizes a unified RGBA8 color model to manage pixel data across its rendering pipeline. This model serves as the project-wide standard for all graphical primitives, including the Canvas pixel buffer, shape fills, text styling, and sprite bitmaps. By standardizing on an 8-bit per channel (32-bit total) format, the system ensures consistent color representation from initial data loading to final transmission via the Kitty Graphics Protocol.
Color management is primarily handled within guiltty-core, which provides the underlying data structures, and is consumed by guiltty-kitty for terminal rendering. The library guarantees that all external image formats (e.g., RGB, grayscale) are normalized to this RGBA8 model during the ingestion process.
Sources: crates/guiltty-core/src/lib.rs:7-11, README.md:16, tasks/plan.md:120-123
The Color Data Structure
The core of the color management system is the Color struct. It stores four 8-bit unsigned integers representing Red, Green, Blue, and Alpha channels.
| Field | Type | Description |
|---|---|---|
r | u8 | Red channel intensity (0-255) |
g | u8 | Green channel intensity (0-255) |
b | u8 | Blue channel intensity (0-255) |
a | u8 | Alpha (transparency) channel (0=transparent, 255=opaque) |
Sources: crates/guiltty-core/src/lib.rs:8-13
Construction Methods
The Color API provides convenience methods for creating opaque or transparent colors:
rgb(r, g, b): Creates a fully opaque color by setting the alpha channel to 255.rgba(r, g, b, a): Creates a color with explicit transparency levels.default(): Returns a fully transparent color (all channels set to 0).
Sources: crates/guiltty-core/src/lib.rs:16-25, crates/guiltty-core/src/lib.rs:114-115
Color Ingestion and Normalization
Guiltty enforces a strict normalization policy where any graphical input must be converted to RGBA8 before it can be used. This is most evident in the Bitmap::from_file implementation, which uses the image crate to decode various formats.
The diagram shows the transformation flow from disk-based image files to the internal RGBA8 representation.
When loading images that lack an alpha channel (such as standard RGB or Grayscale), the system automatically assigns a fully opaque default alpha value (255) during the conversion process.
Sources: crates/guiltty-core/src/lib.rs:446-465, tasks/plan.md:120-125
Color in the Rendering Pipeline
Color data flows from primitives through the Canvas and finally to the Backend.
Canvas Pixel Storage
The Canvas maintains a Vec<Color> as its primary pixel buffer. This buffer is row-major and origin top-left.
- Filling: Shapes use a
Fillenum, which currently supportsFill::Solid(Color). - Text:
TextStyleincludes aColorfield used for rendering glyph pixels. - Sprites:
Spriteobjects contain aBitmap(a collection ofColor). Duringdraw_sprite, pixels are copied to the canvas.
Sources: crates/guiltty-core/src/lib.rs:107-111, crates/guiltty-core/src/lib.rs:218-221, crates/guiltty-core/src/lib.rs:253-256
Alpha Handling in Composition
While the system uses RGBA8, full alpha blending is not implemented in the current version (v0). Instead, the system uses a binary transparency check during sprite drawing:
- If
alpha == 0, the pixel is skipped (transparent). - If
alpha != 0, the pixel replaces the background color entirely.
Sources: crates/guiltty-core/src/lib.rs:563-580
Kitty Protocol Transmission
For terminal display, the RGBA8 data must be serialized into a format the Kitty Graphics Protocol understands. This involves flattening the Color structs into a raw byte stream.
Serialization Process
The Canvas::rgba8_bytes() method flattens the Vec<Color> into a Vec<u8>. Each pixel contributes exactly 4 bytes in the order: R, G, B, A.
This diagram illustrates the conversion of high-level Color structures into the protocol-specific byte stream.
Protocol Configuration
The KittyBackend configures the escape sequence with f=32, which explicitly tells the terminal to expect 32-bit RGBA data.
Sources: crates/guiltty-core/src/lib.rs:154-161, crates/guiltty-kitty/src/lib.rs:81-92, crates/guiltty-kitty/src/lib.rs:14-15
Summary of Color Components
| Component | Role | File Reference |
|---|---|---|
Color | Primary RGBA8 data structure. | guiltty-core/src/lib.rs |
Fill | Defines how shapes are painted (Solid). | guiltty-core/src/lib.rs |
Bitmap | Container for RGBA8 image data. | guiltty-core/src/lib.rs |
image crate | External dependency for format normalization. | guiltty-core/Cargo.toml |
base64 crate | Used for protocol transmission of color data. | guiltty-kitty/Cargo.toml |
Sources: crates/guiltty-core/src/lib.rs:8, crates/guiltty-core/src/lib.rs:253, crates/guiltty-core/Cargo.toml:13, crates/guiltty-kitty/Cargo.toml:11