in vncclient/encoding.go [881:937]
func (t *TightEncoding) basicCompressionReader(r io.Reader, size int, stream uint8) (out io.Reader, err error) {
// After the pixel data has been filtered with one of the above three
// filters, it is compressed using the zlib library. But if the data
// size after applying the filter but before the compression is less
// then 12, then the data is sent as is, uncompressed.
if size < 12 {
return io.LimitReader(r, int64(size)), nil
}
// Four separate zlib streams (0..3) can be used and the
// decoder should read the actual stream id from the
// compression-control byte (see [NOTE1]).
//
// If the compression is not used, then the pixel data is sent
// as is, otherwise the data stream looks like this:
//
// +--------------+----------+----------------------------------+
// | No. of bytes | Type | Description |
// +--------------+----------+----------------------------------+
// | 1-3 | | length in compact representation |
// +--------------+----------+----------------------------------+
// | length | U8 array | zlibData |
// +--------------+----------+----------------------------------+
length, err := t.readCompactLength(byteIOReader{Reader: r})
if err != nil {
return nil, errors.Trace(err)
}
t.size += length
buf := t.streamBufs[stream]
if t.reset&(1<<stream) != 0 {
buf.Reset()
}
buf.Grow(length)
if _, err = buf.ReadFrom(io.LimitReader(r, int64(length))); err != nil {
return nil, errors.Trace(err)
}
if t.streams[stream] == nil {
zr, err := zlib.NewReader(buf)
if err != nil {
return nil, errors.Trace(err)
}
t.streams[stream] = zr.(readCloseResetter)
}
// NOTE1: The decoder must reset the zlib streams before
// decoding the rectangle, if some of the bits 0, 1, 2 and 3 in
// the compression-control byte are set to 1. Note that the
// decoder must reset the indicated zlib streams even if the
// compression type is FillCompression or JpegCompression.
if t.reset&(1<<stream) != 0 {
t.streams[stream].Reset(buf, nil)
t.reset &^= 1 << stream
}
return t.streams[stream], nil
}