PhytonUtils/compression/decompress.go
2023-10-06 09:01:01 +02:00

55 lines
1.2 KiB
Go

package compression
import (
"bytes"
"errors"
"github.com/icza/bitio"
)
func FirmwareBlockDecompress(data []byte) (output []byte, err error) {
windowIndex := WindowInitialIndex
output = make([]byte, 0, DataMaxSize)
window := CreateWindow()
windowBuffer := make([]byte, len(window))
r := bitio.NewReader(bytes.NewReader(data))
var buf []byte
var isLiteral bool
var length, literal, offsetIndex uint64
for {
if isLiteral, err = r.ReadBool(); err != nil {
break
}
if !isLiteral {
if offsetIndex, err = r.ReadBits(OffsetBits); err != nil {
break
} else if length, err = r.ReadBits(LengthBits); err != nil {
return nil, err
} else if length += MaxUncoded; DataMaxSize < (length + uint64(len(output))) {
return nil, errors.New("out of bounds output")
}
windowIndex, buf = window.GetSet(int(offsetIndex), windowIndex, int(length), windowBuffer)
output = append(output, buf...)
} else {
if literal, err = r.ReadBits(LiteralBits); err != nil {
break
} else if (DataMaxSize - 1) < len(output) {
return nil, errors.New("out of bounds output")
}
output = append(output, byte(literal))
windowIndex = window.SetByte(windowIndex, byte(literal))
}
}
return output, nil
}