ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
image.c File Reference

Go to the source code of this file.

Macros

#define KITTY_BASE64_CHUNK_SIZE   4096
#define KITTY_RAW_CHUNK_SIZE   (KITTY_BASE64_CHUNK_SIZE / 4 * 3)
#define KITTY_FRAMING_BUFFER_SIZE   128
#define MEDIA_KITTY_IMAGE_PACKET_BUFFER_SIZE   (KITTY_BASE64_CHUNK_SIZE + KITTY_FRAMING_BUFFER_SIZE)

Functions

asciichat_error_t kitty_image_write (FILE *stream, const uint8_t *rgba, int width, int height, int pitch)

Macro Definition Documentation

◆ KITTY_BASE64_CHUNK_SIZE

#define KITTY_BASE64_CHUNK_SIZE   4096

Definition at line 3 of file media/kitty/image.c.

◆ KITTY_FRAMING_BUFFER_SIZE

#define KITTY_FRAMING_BUFFER_SIZE   128

Definition at line 5 of file media/kitty/image.c.

◆ KITTY_RAW_CHUNK_SIZE

#define KITTY_RAW_CHUNK_SIZE   (KITTY_BASE64_CHUNK_SIZE / 4 * 3)

Definition at line 4 of file media/kitty/image.c.

Referenced by kitty_image_write().

◆ MEDIA_KITTY_IMAGE_PACKET_BUFFER_SIZE

#define MEDIA_KITTY_IMAGE_PACKET_BUFFER_SIZE   (KITTY_BASE64_CHUNK_SIZE + KITTY_FRAMING_BUFFER_SIZE)

Definition at line 6 of file media/kitty/image.c.

Referenced by kitty_image_write().

Function Documentation

◆ kitty_image_write()

asciichat_error_t kitty_image_write ( FILE * stream,
const uint8_t * rgba,
int width,
int height,
int pitch )

Transmit packed RGBA pixels using Kitty's direct, chunked graphics protocol. Padding at the end of each input row is excluded. The stream remains caller-owned.

Definition at line 14 of file media/kitty/image.c.

14 {
15 if (!stream || !rgba || width <= 0 || height <= 0 || width > INT_MAX / 4 || pitch < width * 4 ||
16 (size_t)height > SIZE_MAX / (size_t)pitch)
17 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid Kitty image dimensions or pixels");
18
19 // 3072 raw bytes produce the protocol maximum of 4096 base64 bytes.
20 static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
21 const size_t row_bytes = (size_t)width * 4;
22 const size_t total = row_bytes * (size_t)height;
23 size_t offset = 0;
24 bool first = true;
25 while (offset < total) {
27 size_t count = total - offset;
28 if (count > KITTY_RAW_CHUNK_SIZE)
30 bool more = offset + count < total;
31 int prefix = first ? snprintf(packet, sizeof(packet), "\033_Ga=T,f=32,s=%d,v=%d,t=d,q=2,m=%d;", width, height, more)
32 : snprintf(packet, sizeof(packet), "\033_Gm=%d;", more);
33 size_t used = (size_t)prefix;
34 for (size_t i = 0; i < count; i += 3) {
35 uint32_t triple = 0;
36 size_t available = count - i < 3 ? count - i : 3;
37 for (size_t j = 0; j < available; ++j) {
38 size_t index = offset + i + j;
39 triple |= (uint32_t)rgba[(index / row_bytes) * (size_t)pitch + index % row_bytes] << (16 - 8 * j);
40 }
41 packet[used++] = alphabet[(triple >> 18) & 63];
42 packet[used++] = alphabet[(triple >> 12) & 63];
43 packet[used++] = available > 1 ? alphabet[(triple >> 6) & 63] : '=';
44 packet[used++] = available > 2 ? alphabet[triple & 63] : '=';
45 }
46 packet[used++] = '\033';
47 packet[used++] = '\\';
49 asciichat_error_t err = stdout_writer_write(stream, packet, used);
51 if (err != ASCIICHAT_OK)
52 return err;
53 offset += count;
54 first = false;
55 }
56 return ASCIICHAT_OK;
57}
#define SET_ERRNO(code,...)
unsigned int height
Definition fft.c:23
unsigned int width
Definition fft.c:23
unsigned int uint32_t
Definition common.h:62
asciichat_error_t
Error and exit codes - unified status values (0-255).
Definition error_codes.h:44
@ ASCIICHAT_OK
Definition error_codes.h:46
@ ERROR_INVALID_PARAM
#define KITTY_RAW_CHUNK_SIZE
#define MEDIA_KITTY_IMAGE_PACKET_BUFFER_SIZE
static bool size_t index
Definition queries.h:8
asciichat_error_t stdout_writer_write(FILE *stream, const void *data, size_t size)
void ui_controller_packet_begin(void)
void ui_controller_packet_end(void)

References ASCIICHAT_OK, ERROR_INVALID_PARAM, height, index, KITTY_RAW_CHUNK_SIZE, MEDIA_KITTY_IMAGE_PACKET_BUFFER_SIZE, SET_ERRNO, stdout_writer_write(), ui_controller_packet_begin(), ui_controller_packet_end(), and width.

Referenced by render_file_destroy().