/packet/rle.go
package packet

import (
    "fmt"

    "bytex64.net/code/bitsmash/ac"
)

type RLEPacket struct {
    color uint8
    length uint8
}

func (self *RLEPacket) Length() int {
    return int(self.length)
}

func (self *RLEPacket) ByteLength() int {
    return 1
}

func (self *RLEPacket) Encode(encoder ac.CodecManager) {
    encoder.Encode(CONTEXT_COLOR, uint32(self.color))
    encoder.Encode(CONTEXT_RLE_REPEAT, uint32(self.length - 2))
}

func DecodeRLE(decoder ac.CodecManager) Packet {
    color := byte(decoder.Decode(CONTEXT_COLOR))
    length := byte(decoder.Decode(CONTEXT_RLE_REPEAT))
    return &RLEPacket{color, length + 2}
}

func (self *RLEPacket) Pixels() []uint8 {
    px := make([]uint8, self.length)
    for i := 0; i < int(self.length); i++ {
        px[i] = self.color
    }
    return px
}

func (self *RLEPacket) String() string {
    return fmt.Sprintf("RLE color %d length %d", self.color, self.length)
}

func ScanRLE(pixels []uint8) Packet {
    i := 1
    var maxlen int
    if len(pixels) > 17 {
        maxlen = 17
    } else {
        maxlen = len(pixels)
    }
    for i < maxlen && pixels[i] == pixels[0] {
        i++
    }
    if i > 2 {
        return &RLEPacket{pixels[0], uint8(i)}
    } else {
        return nil
    }
}