simplify encode/decode of RAW encoding

Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru>
This commit is contained in:
Василий Толстов 2017-06-20 12:32:09 +03:00
parent 0f07f3fc63
commit 87294a7677
2 changed files with 67 additions and 28 deletions

View File

@ -326,53 +326,34 @@ func readTightLength(c Conn) (int, error) {
}
func (enc *RawEncoding) Write(c Conn, rect *Rectangle) error {
buf := bPool.Get().(*bytes.Buffer)
buf.Reset()
defer bPool.Put(buf)
n := 0
for _, c := range enc.Colors {
bytes, err := c.Marshal()
if err != nil {
return err
}
n += len(bytes)
if err := binary.Write(buf, binary.BigEndian, bytes); err != nil {
return err
var err error
for _, clr := range enc.Colors {
if err = clr.Write(c); err != nil {
break
}
}
_, err := buf.WriteTo(c)
return err
}
// Read implements the Encoding interface.
func (enc *RawEncoding) Read(c Conn, rect *Rectangle) error {
buf := bPool.Get().(*bytes.Buffer)
buf.Reset()
defer bPool.Put(buf)
var err error
pf := c.PixelFormat()
cm := c.ColorMap()
bytesPerPixel := int(pf.BPP / 8)
n := rect.Area() * bytesPerPixel
data := make([]byte, n)
if err := binary.Read(c, binary.BigEndian, &data); err != nil {
return err
}
buf.Write(data)
colors := make([]Color, rect.Area())
Loop:
for y := uint16(0); y < rect.Height; y++ {
for x := uint16(0); x < rect.Width; x++ {
color := NewColor(pf, cm)
if err := color.Unmarshal(buf.Next(bytesPerPixel)); err != nil {
return err
if err = color.Read(c); err != nil {
break Loop
}
colors[int(y)*int(rect.Width)+int(x)] = *color
}
}
enc.Colors = colors
return nil
return err
}
func (*RawEncoding) Type() EncodingType { return EncRaw }

View File

@ -39,6 +39,28 @@ func NewRectangle() *Rectangle {
return &Rectangle{}
}
func (clr *Color) Write(c Conn) error {
var err error
order := clr.pf.order()
pixel := clr.cmIndex
if clr.pf.TrueColor == 1 {
pixel = uint32(clr.R) << clr.pf.RedShift
pixel |= uint32(clr.G) << clr.pf.GreenShift
pixel |= uint32(clr.B) << clr.pf.BlueShift
}
switch clr.pf.BPP {
case 8:
err = binary.Write(c, order, byte(pixel))
case 16:
err = binary.Write(c, order, uint16(pixel))
case 32:
err = binary.Write(c, order, uint32(pixel))
}
return err
}
// Marshal implements the Marshaler interface.
func (c *Color) Marshal() ([]byte, error) {
order := c.pf.order()
@ -65,6 +87,42 @@ func (c *Color) Marshal() ([]byte, error) {
return bytes, nil
}
func (clr *Color) Read(c Conn) error {
order := clr.pf.order()
var pixel uint32
switch clr.pf.BPP {
case 8:
var px uint8
if err := binary.Read(c, order, &px); err != nil {
return err
}
pixel = uint32(px)
case 16:
var px uint16
if err := binary.Read(c, order, &px); err != nil {
return err
}
pixel = uint32(px)
case 32:
var px uint32
if err := binary.Read(c, order, &px); err != nil {
return err
}
pixel = uint32(px)
}
if clr.pf.TrueColor == 1 {
clr.R = uint16((pixel >> clr.pf.RedShift) & uint32(clr.pf.RedMax))
clr.G = uint16((pixel >> clr.pf.GreenShift) & uint32(clr.pf.GreenMax))
clr.B = uint16((pixel >> clr.pf.BlueShift) & uint32(clr.pf.BlueMax))
} else {
*clr = clr.cm[pixel]
clr.cmIndex = pixel
}
return nil
}
// Unmarshal implements the Unmarshaler interface.
func (c *Color) Unmarshal(data []byte) error {
if len(data) == 0 {