ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
background.c File Reference

Scalar ASCII background color rendering (truecolor) More...

Go to the source code of this file.

Functions

char * image_print_color_background (const image_t *p, const char *palette)
 Convert image to colored ASCII art with background colors.
 

Detailed Description

Scalar ASCII background color rendering (truecolor)

Renders images using ANSI truecolor background colors with contrasting foreground text. Background is set to the pixel color, foreground is white on dark pixels, black on bright pixels.

Definition in file background.c.

Function Documentation

◆ image_print_color_background()

char * image_print_color_background ( const image_t *  p,
const char *  palette 
)

Convert image to colored ASCII art with background colors.

Parameters
pImage pointer
paletteCharacter palette for luminance mapping
Returns
Allocated ASCII string with background color codes (caller must free), or NULL on error

Definition at line 17 of file background.c.

17 {
18 if (!p || !palette || !p->pixels) {
19 return NULL;
20 }
21
22 utf8_palette_cache_t *utf8_cache = get_utf8_palette_cache(palette);
23 if (!utf8_cache) {
24 return NULL;
25 }
26
27 const int h = p->h;
28 const int w = p->w;
29 const size_t h_sz = (size_t)h;
30 const size_t w_sz = (size_t)w;
31
32 if (h_sz > 0 && w_sz > SIZE_MAX / h_sz) {
33 return NULL;
34 }
35
36 // Each pixel needs: bg sequence (~19) + fg sequence (~19) + char (up to 4) + possible reset
37 const size_t bytes_per_pixel = 50;
38 const size_t total_pixels = h_sz * w_sz;
39 const size_t lines_size = total_pixels * bytes_per_pixel + h_sz + 16;
40
41 char *lines;
42 lines = SAFE_MALLOC(lines_size, char *);
43
44 char *ptr = lines;
45 const rgb_pixel_t *pix = p->pixels;
46
47 for (int y = 0; y < h; y++) {
48 const int row_offset = y * w;
49
50 for (int x = 0; x < w; x++) {
51 const rgb_pixel_t pixel = pix[row_offset + x];
52
53 // Set background to pixel color
54 ptr += SAFE_SNPRINTF(ptr, 20, "\033[48;2;%d;%d;%dm", pixel.r, pixel.g, pixel.b);
55
56 // Choose contrasting foreground: white on dark, black on bright
57 int luminance = (77 * pixel.r + 150 * pixel.g + 29 * pixel.b + 128) >> 8;
58 if (luminance < 128) {
59 ptr += SAFE_SNPRINTF(ptr, 20, "\033[38;2;255;255;255m");
60 } else {
61 ptr += SAFE_SNPRINTF(ptr, 20, "\033[38;2;0;0;0m");
62 }
63
64 // Select character based on luminance
65 uint8_t safe_luminance = clamp_rgb(luminance);
66 const utf8_char_t *char_info = &utf8_cache->cache[safe_luminance];
67 for (int i = 0; i < char_info->byte_len; i++) {
68 *ptr++ = char_info->utf8_bytes[i];
69 }
70 }
71
72 // Reset and newline
73 *ptr++ = '\033';
74 *ptr++ = '[';
75 *ptr++ = '0';
76 *ptr++ = 'm';
77 if (y < h - 1) {
78 *ptr++ = '\n';
79 }
80 }
81
82 *ptr = '\0';
83 return lines;
84}
#define SAFE_MALLOC(size, cast)
Definition common.h:264
#define SAFE_SNPRINTF(buffer, buffer_size,...)
Definition common.h:492
unsigned char uint8_t
Definition common.h:56
uint8_t utf8_bytes[4]
utf8_palette_cache_t * get_utf8_palette_cache(const char *ascii_chars)
Get UTF-8 palette cache for a character set.
utf8_char_t cache[256]
int w
Image width in pixels (must be > 0)
int h
Image height in pixels (must be > 0)
rgb_pixel_t * pixels
Pixel data array (width * height RGB pixels, row-major order)
RGB pixel structure.
uint8_t b
Blue color component (0-255)
uint8_t g
Green color component (0-255)
uint8_t r
Red color component (0-255)

References rgb_pixel_t::b, utf8_char_t::byte_len, utf8_palette_cache::cache, rgb_pixel_t::g, get_utf8_palette_cache(), image_t::h, image_t::pixels, rgb_pixel_t::r, SAFE_MALLOC, SAFE_SNPRINTF, utf8_char_t::utf8_bytes, and image_t::w.

Referenced by ascii_convert(), and image_print_with_capabilities().