Get 24 bit RGB transmission working

This commit is contained in:
Kovid Goyal
2023-01-02 17:43:32 +05:30
parent 6291d0d400
commit 4623f580b9
4 changed files with 68 additions and 29 deletions

View File

@@ -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 final_img image.Image
if is_opaque || remove_alpha != nil {
var rgb *images.NRGB
m, err := shm.CreateTemp("icat-*", uint64(f.width*f.height*3))
if err != nil {
rgb = images.NewNRGB(dest_rect)
} else {
rgb = &images.NRGB{Pix: m.Slice(), Stride: 3 * f.width, Rect: dest_rect}
f.shm = m
}
imgd.format_uppercase = "RGB"
f.in_memory_bytes = rgb.Pix
final_img = rgb
} else {
var rgba *image.NRGBA var rgba *image.NRGBA
m, err := shm.CreateTemp("icat-*", uint64(f.width*f.height*4)) m, err := shm.CreateTemp("icat-*", uint64(f.width*f.height*4))
if err != nil { if err != nil {
rgba = image.NewNRGBA(dest_rect) rgba = image.NewNRGBA(dest_rect)
} else { } else {
rgba = &image.NRGBA{ rgba = &image.NRGBA{Pix: m.Slice(), Stride: 4 * f.width, Rect: dest_rect}
Pix: m.Slice(),
Stride: 4 * f.width,
Rect: dest_rect,
}
f.shm = m f.shm = m
} }
images.PasteCenter(rgba, img, remove_alpha)
imgd.format_uppercase = "RGBA" imgd.format_uppercase = "RGBA"
f.in_memory_bytes = rgba.Pix f.in_memory_bytes = rgba.Pix
final_img = rgba
}
images.PasteCenter(final_img, img, remove_alpha)
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 {
return
}
// reset the sizes as we read EXIF tags here which could have rotated the image // reset the sizes as we read EXIF tags here which could have rotated the image
imgd.canvas_width = img.Bounds().Dx() imgd.canvas_width = img.Bounds().Dx()
imgd.canvas_height = img.Bounds().Dy() imgd.canvas_height = img.Bounds().Dy()
set_basic_metadata(imgd) 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
} }

View File

@@ -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()
} }

View File

@@ -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,
}
}

View File

@@ -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")
} }