| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- package kitty
- import (
- "compress/zlib"
- "fmt"
- "image"
- "image/png"
- "io"
- )
- // Encoder is an encoder for the Kitty graphics protocol. It supports encoding
- // images in the 24-bit [RGB], 32-bit [RGBA], and [PNG] formats, and
- // compressing the data using zlib.
- // The default format is 32-bit [RGBA].
- type Encoder struct {
- // Uses zlib compression.
- Compress bool
- // Can be one of [RGBA], [RGB], or [PNG].
- Format int
- }
- // Encode encodes the image data in the specified format and writes it to w.
- func (e *Encoder) Encode(w io.Writer, m image.Image) error {
- if m == nil {
- return nil
- }
- if e.Compress {
- zw := zlib.NewWriter(w)
- defer zw.Close() //nolint:errcheck
- w = zw
- }
- if e.Format == 0 {
- e.Format = RGBA
- }
- switch e.Format {
- case RGBA, RGB:
- bounds := m.Bounds()
- for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
- for x := bounds.Min.X; x < bounds.Max.X; x++ {
- r, g, b, a := m.At(x, y).RGBA()
- switch e.Format {
- case RGBA:
- w.Write([]byte{byte(r >> 8), byte(g >> 8), byte(b >> 8), byte(a >> 8)}) //nolint:errcheck
- case RGB:
- w.Write([]byte{byte(r >> 8), byte(g >> 8), byte(b >> 8)}) //nolint:errcheck
- }
- }
- }
- case PNG:
- if err := png.Encode(w, m); err != nil {
- return fmt.Errorf("failed to encode PNG: %w", err)
- }
- default:
- return fmt.Errorf("unsupported format: %d", e.Format)
- }
- return nil
- }
|