package stego import ( "encoding/base64" "fmt" "strings" ) // KittyEscape кодирует PNG-байты в escape-последовательность протокола // Kitty graphics — Konsole его понимает (это уже выяснялось раньше, на // другом проекте, где графические протоколы работали в Konsole, но не // в Alacritty). // // ЧЕСТНАЯ ОГОВОРКА, серьёзнее обычной: сама генерация escape-кода по // спецификации протокола — то, что я действительно знаю и могу // аргументировать (a=T — передать и сразу отобразить одним действием; // f=100 — формат PNG, протокол умеет декодировать его сам, кодировать // в сырой RGBA не нужно; t=d — данные идут прямо в escape-последовательности, // не через файл; чанки по 4096 base64-байт — так требует спецификация // для больших изображений). А вот что произойдёт, когда bubbletea в // alt-screen режиме в следующий раз перерисует экран поверх уже // показанной Kitty-картинки — я предсказать не могу совсем: там нет // реального терминала, чтобы проверить. Другие непроверенные места в // проекте (например, зависимость на sqlite) — это "может не // скомпилироваться, поправишь по ошибке компилятора". Здесь другое: // код скомпилируется и, скорее всего, отработает без паники, вопрос // только в том, что увидишь на экране — и тут я честно не знаю. Отсюда // клавиша ctrl+v на вкладке Steganography — передать escape-код заново, // если картинку перекрыло перерисовкой TUI. func KittyEscape(pngData []byte) string { b64 := base64.StdEncoding.EncodeToString(pngData) const chunkSize = 4096 var b strings.Builder for i := 0; i < len(b64); i += chunkSize { end := i + chunkSize if end > len(b64) { end = len(b64) } chunk := b64[i:end] more := 0 if end < len(b64) { more = 1 } if i == 0 { fmt.Fprintf(&b, "\x1b_Ga=T,f=100,t=d,m=%d;%s\x1b\\", more, chunk) } else { fmt.Fprintf(&b, "\x1b_Gm=%d;%s\x1b\\", more, chunk) } } return b.String() }