157 lines
3.4 KiB
Go
157 lines
3.4 KiB
Go
package vnc
|
|
|
|
import (
|
|
"image"
|
|
)
|
|
|
|
//var _ draw.Drawer = (*ServerConn)(nil)
|
|
//var _ draw.Image = (*ServerConn)(nil)
|
|
|
|
// Color represents a single color in a color map.
|
|
type Color struct {
|
|
pf *PixelFormat
|
|
cm *ColorMap
|
|
cmIndex uint32 // Only valid if pf.TrueColor is false.
|
|
R, G, B uint16
|
|
}
|
|
|
|
type ColorMap [256]Color
|
|
|
|
// NewColor returns a new Color object.
|
|
func NewColor(pf *PixelFormat, cm *ColorMap) *Color {
|
|
return &Color{
|
|
pf: pf,
|
|
cm: cm,
|
|
}
|
|
}
|
|
|
|
// Rectangle represents a rectangle of pixel data.
|
|
type Rectangle struct {
|
|
X, Y uint16
|
|
Width, Height uint16
|
|
Enc Encoding
|
|
}
|
|
|
|
// Marshal implements the Marshaler interface.
|
|
func (c *Color) Marshal() ([]byte, error) {
|
|
order := c.pf.order()
|
|
pixel := c.cmIndex
|
|
if c.pf.TrueColor == 1 {
|
|
pixel = uint32(c.R) << c.pf.RedShift
|
|
pixel |= uint32(c.G) << c.pf.GreenShift
|
|
pixel |= uint32(c.B) << c.pf.BlueShift
|
|
}
|
|
|
|
var bytes []byte
|
|
switch c.pf.BPP {
|
|
case 8:
|
|
bytes = make([]byte, 1)
|
|
bytes[0] = byte(pixel)
|
|
case 16:
|
|
bytes = make([]byte, 2)
|
|
order.PutUint16(bytes, uint16(pixel))
|
|
case 32:
|
|
bytes = make([]byte, 4)
|
|
order.PutUint32(bytes, pixel)
|
|
}
|
|
|
|
return bytes, nil
|
|
}
|
|
|
|
// Unmarshal implements the Unmarshaler interface.
|
|
func (c *Color) Unmarshal(data []byte) error {
|
|
if len(data) == 0 {
|
|
return nil
|
|
}
|
|
|
|
order := c.pf.order()
|
|
|
|
var pixel uint32
|
|
switch c.pf.BPP {
|
|
case 8:
|
|
pixel = uint32(data[0])
|
|
case 16:
|
|
pixel = uint32(order.Uint16(data))
|
|
case 32:
|
|
pixel = order.Uint32(data)
|
|
}
|
|
|
|
if c.pf.TrueColor == 1 {
|
|
c.R = uint16((pixel >> c.pf.RedShift) & uint32(c.pf.RedMax))
|
|
c.G = uint16((pixel >> c.pf.GreenShift) & uint32(c.pf.GreenMax))
|
|
c.B = uint16((pixel >> c.pf.BlueShift) & uint32(c.pf.BlueMax))
|
|
} else {
|
|
*c = c.cm[pixel]
|
|
c.cmIndex = pixel
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func colorsToImage(x, y, width, height uint16, colors []Color) *image.RGBA64 {
|
|
rect := image.Rect(int(x), int(y), int(x+width), int(y+height))
|
|
rgba := image.NewRGBA64(rect)
|
|
a := uint16(1)
|
|
for i, color := range colors {
|
|
rgba.Pix[4*i+0] = uint8(color.R >> 8)
|
|
rgba.Pix[4*i+1] = uint8(color.R)
|
|
rgba.Pix[4*i+2] = uint8(color.G >> 8)
|
|
rgba.Pix[4*i+3] = uint8(color.G)
|
|
rgba.Pix[4*i+4] = uint8(color.B >> 8)
|
|
rgba.Pix[4*i+5] = uint8(color.B)
|
|
rgba.Pix[4*i+6] = uint8(a >> 8)
|
|
rgba.Pix[4*i+7] = uint8(a)
|
|
}
|
|
return rgba
|
|
}
|
|
|
|
// Marshal implements the Marshaler interface.
|
|
func (r *Rectangle) Marshal() ([]byte, error) {
|
|
/*
|
|
buf := bytes.NewBuffer(nil)
|
|
|
|
var msg Rectangle
|
|
msg.X, msg.Y, msg.W, msg.H = r.X, r.Y, r.Width, r.Height
|
|
msg.E = r.Enc.Type()
|
|
if err := binary.Write(buf, binary.BigEndian, msg); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
bytes, err := r.Enc.Marshal()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err := binary.Write(buf, binary.BigEndian, bytes); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return buf.Bytes(), nil
|
|
*/
|
|
return nil, nil
|
|
}
|
|
|
|
// Unmarshal implements the Unmarshaler interface.
|
|
func (r *Rectangle) Unmarshal(data []byte) error {
|
|
/*
|
|
buf := bytes.NewBuffer(data)
|
|
|
|
var msg Rectangle
|
|
if err := binary.Read(buf, binary.BigEndian, &msg); err != nil {
|
|
return err
|
|
}
|
|
r.X, r.Y, r.Width, r.Height = msg.X, msg.Y, msg.W, msg.H
|
|
|
|
switch msg.E {
|
|
case encodings.Raw:
|
|
r.Enc = &RawEncoding{}
|
|
default:
|
|
return fmt.Errorf("unable to unmarshal encoding %v", msg.E)
|
|
}
|
|
return nil
|
|
*/
|
|
return nil
|
|
}
|
|
|
|
// Area returns the total area in pixels of the Rectangle.
|
|
func (r *Rectangle) Area() int { return int(r.Width) * int(r.Height) }
|