mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 14:18:26 +02:00
Get 24 bit RGB transmission working
This commit is contained in:
@@ -13,7 +13,7 @@ import (
|
|||||||
|
|
||||||
var _ = fmt.Print
|
var _ = fmt.Print
|
||||||
|
|
||||||
func add_frame(imgd *image_data, img image.Image) {
|
func add_frame(imgd *image_data, img image.Image, is_opaque bool) {
|
||||||
if flip {
|
if flip {
|
||||||
img = imaging.FlipV(img)
|
img = imaging.FlipV(img)
|
||||||
}
|
}
|
||||||
@@ -23,33 +23,48 @@ func add_frame(imgd *image_data, img image.Image) {
|
|||||||
b := img.Bounds()
|
b := img.Bounds()
|
||||||
f := image_frame{width: b.Dx(), height: b.Dy()}
|
f := image_frame{width: b.Dx(), height: b.Dy()}
|
||||||
dest_rect := image.Rect(0, 0, f.width, f.height)
|
dest_rect := image.Rect(0, 0, f.width, f.height)
|
||||||
var rgba *image.NRGBA
|
var final_img image.Image
|
||||||
m, err := shm.CreateTemp("icat-*", uint64(f.width*f.height*4))
|
|
||||||
if err != nil {
|
if is_opaque || remove_alpha != nil {
|
||||||
rgba = image.NewNRGBA(dest_rect)
|
var rgb *images.NRGB
|
||||||
} else {
|
m, err := shm.CreateTemp("icat-*", uint64(f.width*f.height*3))
|
||||||
rgba = &image.NRGBA{
|
if err != nil {
|
||||||
Pix: m.Slice(),
|
rgb = images.NewNRGB(dest_rect)
|
||||||
Stride: 4 * f.width,
|
} else {
|
||||||
Rect: dest_rect,
|
rgb = &images.NRGB{Pix: m.Slice(), Stride: 3 * f.width, Rect: dest_rect}
|
||||||
|
f.shm = m
|
||||||
}
|
}
|
||||||
f.shm = m
|
imgd.format_uppercase = "RGB"
|
||||||
|
f.in_memory_bytes = rgb.Pix
|
||||||
|
final_img = rgb
|
||||||
|
} else {
|
||||||
|
var rgba *image.NRGBA
|
||||||
|
m, err := shm.CreateTemp("icat-*", uint64(f.width*f.height*4))
|
||||||
|
if err != nil {
|
||||||
|
rgba = image.NewNRGBA(dest_rect)
|
||||||
|
} else {
|
||||||
|
rgba = &image.NRGBA{Pix: m.Slice(), Stride: 4 * f.width, Rect: dest_rect}
|
||||||
|
f.shm = m
|
||||||
|
}
|
||||||
|
imgd.format_uppercase = "RGBA"
|
||||||
|
f.in_memory_bytes = rgba.Pix
|
||||||
|
final_img = rgba
|
||||||
}
|
}
|
||||||
images.PasteCenter(rgba, img, remove_alpha)
|
images.PasteCenter(final_img, img, remove_alpha)
|
||||||
imgd.format_uppercase = "RGBA"
|
|
||||||
f.in_memory_bytes = rgba.Pix
|
|
||||||
imgd.frames = append(imgd.frames, &f)
|
imgd.frames = append(imgd.frames, &f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func load_one_frame_image(imgd *image_data, src *opened_input) (image.Image, error) {
|
func load_one_frame_image(imgd *image_data, src *opened_input) (img image.Image, is_opaque bool, err error) {
|
||||||
img, err := imaging.Decode(src.file, imaging.AutoOrientation(true))
|
img, err = imaging.Decode(src.file, imaging.AutoOrientation(true))
|
||||||
src.Rewind()
|
src.Rewind()
|
||||||
if err == nil {
|
if err != nil {
|
||||||
// reset the sizes as we read EXIF tags here which could have rotated the image
|
return
|
||||||
imgd.canvas_width = img.Bounds().Dx()
|
|
||||||
imgd.canvas_height = img.Bounds().Dy()
|
|
||||||
set_basic_metadata(imgd)
|
|
||||||
}
|
}
|
||||||
|
// reset the sizes as we read EXIF tags here which could have rotated the image
|
||||||
|
imgd.canvas_width = img.Bounds().Dx()
|
||||||
|
imgd.canvas_height = img.Bounds().Dy()
|
||||||
|
set_basic_metadata(imgd)
|
||||||
|
is_opaque = images.IsOpaque(img)
|
||||||
if imgd.needs_scaling {
|
if imgd.needs_scaling {
|
||||||
if imgd.canvas_width < imgd.available_width && opts.ScaleUp && place != nil {
|
if imgd.canvas_width < imgd.available_width && opts.ScaleUp && place != nil {
|
||||||
r := float64(imgd.available_width) / float64(imgd.canvas_width)
|
r := float64(imgd.available_width) / float64(imgd.canvas_width)
|
||||||
@@ -59,7 +74,7 @@ func load_one_frame_image(imgd *image_data, src *opened_input) (image.Image, err
|
|||||||
img = imaging.Resize(img, imgd.canvas_width, imgd.canvas_height, imaging.Lanczos)
|
img = imaging.Resize(img, imgd.canvas_width, imgd.canvas_height, imaging.Lanczos)
|
||||||
imgd.needs_scaling = false
|
imgd.needs_scaling = false
|
||||||
}
|
}
|
||||||
return img, err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func render_image_with_go(imgd *image_data, src *opened_input) (err error) {
|
func render_image_with_go(imgd *image_data, src *opened_input) (err error) {
|
||||||
@@ -67,11 +82,11 @@ func render_image_with_go(imgd *image_data, src *opened_input) (err error) {
|
|||||||
case "GIF":
|
case "GIF":
|
||||||
return fmt.Errorf("TODO: implement GIF decoding")
|
return fmt.Errorf("TODO: implement GIF decoding")
|
||||||
default:
|
default:
|
||||||
img, err := load_one_frame_image(imgd, src)
|
img, is_opaque, err := load_one_frame_image(imgd, src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
add_frame(imgd, img)
|
add_frame(imgd, img, is_opaque)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ func IsOpaque(img image.Image) bool {
|
|||||||
return img.(*image.Paletted).Opaque()
|
return img.(*image.Paletted).Opaque()
|
||||||
case *image.Uniform:
|
case *image.Uniform:
|
||||||
return img.(*image.Uniform).Opaque()
|
return img.(*image.Uniform).Opaque()
|
||||||
|
case *image.YCbCr:
|
||||||
|
return img.(*image.YCbCr).Opaque()
|
||||||
case *NRGB:
|
case *NRGB:
|
||||||
return img.(*NRGB).Opaque()
|
return img.(*NRGB).Opaque()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ func (s *scanner_rgb) scan(x1, y1, x2, y2 int, dst []uint8) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func paste_nrgb_onto_opaque(background *image.NRGBA, img image.Image, pos image.Point, bgcol *NRGBColor) {
|
func paste_nrgb_onto_opaque(background *NRGB, img image.Image, pos image.Point, bgcol *NRGBColor) {
|
||||||
bg := NRGBColor{}
|
bg := NRGBColor{}
|
||||||
if bgcol != nil {
|
if bgcol != nil {
|
||||||
bg = *bgcol
|
bg = *bgcol
|
||||||
@@ -408,3 +408,11 @@ func paste_nrgb_onto_opaque(background *image.NRGBA, img image.Image, pos image.
|
|||||||
src := newScannerRGB(img, bg)
|
src := newScannerRGB(img, bg)
|
||||||
run_paste(src, background, pos, func(dst []byte) {})
|
run_paste(src, background, pos, func(dst []byte) {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewNRGB(r image.Rectangle) *NRGB {
|
||||||
|
return &NRGB{
|
||||||
|
Pix: make([]uint8, 3*r.Dx()*r.Dy()),
|
||||||
|
Stride: 3 * r.Dx(),
|
||||||
|
Rect: r,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ type Scanner interface {
|
|||||||
bounds() image.Rectangle
|
bounds() image.Rectangle
|
||||||
}
|
}
|
||||||
|
|
||||||
func run_paste(src Scanner, background *image.NRGBA, pos image.Point, postprocess func([]byte)) {
|
func run_paste(src Scanner, background image.Image, pos image.Point, postprocess func([]byte)) {
|
||||||
pos = pos.Sub(background.Bounds().Min)
|
pos = pos.Sub(background.Bounds().Min)
|
||||||
pasteRect := image.Rectangle{Min: pos, Max: pos.Add(src.bounds().Size())}
|
pasteRect := image.Rectangle{Min: pos, Max: pos.Add(src.bounds().Size())}
|
||||||
interRect := pasteRect.Intersect(background.Bounds())
|
interRect := pasteRect.Intersect(background.Bounds())
|
||||||
@@ -338,15 +338,29 @@ func run_paste(src Scanner, background *image.NRGBA, pos image.Point, postproces
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
bytes_per_pixel := src.bytes_per_pixel()
|
bytes_per_pixel := src.bytes_per_pixel()
|
||||||
|
var stride int
|
||||||
|
var pix []uint8
|
||||||
|
switch v := background.(type) {
|
||||||
|
case *image.NRGBA:
|
||||||
|
i := background.(*image.NRGBA)
|
||||||
|
stride = i.Stride
|
||||||
|
pix = i.Pix
|
||||||
|
case *NRGB:
|
||||||
|
i := background.(*NRGB)
|
||||||
|
stride = i.Stride
|
||||||
|
pix = i.Pix
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("Unsupported image type: %v", v))
|
||||||
|
}
|
||||||
parallel(interRect.Min.Y, interRect.Max.Y, func(ys <-chan int) {
|
parallel(interRect.Min.Y, interRect.Max.Y, func(ys <-chan int) {
|
||||||
for y := range ys {
|
for y := range ys {
|
||||||
x1 := interRect.Min.X - pasteRect.Min.X
|
x1 := interRect.Min.X - pasteRect.Min.X
|
||||||
x2 := interRect.Max.X - pasteRect.Min.X
|
x2 := interRect.Max.X - pasteRect.Min.X
|
||||||
y1 := y - pasteRect.Min.Y
|
y1 := y - pasteRect.Min.Y
|
||||||
y2 := y1 + 1
|
y2 := y1 + 1
|
||||||
i1 := y*background.Stride + interRect.Min.X*bytes_per_pixel
|
i1 := y*stride + interRect.Min.X*bytes_per_pixel
|
||||||
i2 := i1 + interRect.Dx()*bytes_per_pixel
|
i2 := i1 + interRect.Dx()*bytes_per_pixel
|
||||||
dst := background.Pix[i1:i2]
|
dst := pix[i1:i2]
|
||||||
src.scan(x1, y1, x2, y2, dst)
|
src.scan(x1, y1, x2, y2, dst)
|
||||||
postprocess(dst)
|
postprocess(dst)
|
||||||
}
|
}
|
||||||
@@ -381,7 +395,7 @@ func Paste(background image.Image, img image.Image, pos image.Point, opaque_bg *
|
|||||||
case *image.NRGBA:
|
case *image.NRGBA:
|
||||||
paste_nrgba_onto_opaque(background.(*image.NRGBA), img, pos, opaque_bg)
|
paste_nrgba_onto_opaque(background.(*image.NRGBA), img, pos, opaque_bg)
|
||||||
case *NRGB:
|
case *NRGB:
|
||||||
paste_nrgb_onto_opaque(background.(*image.NRGBA), img, pos, opaque_bg)
|
paste_nrgb_onto_opaque(background.(*NRGB), img, pos, opaque_bg)
|
||||||
default:
|
default:
|
||||||
panic("Unsupported background image type")
|
panic("Unsupported background image type")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user