Add zstd library

This commit is contained in:
Sascha L. Teichmann
2024-01-05 14:41:06 +01:00
parent d788d55569
commit 827d73bed0
3 changed files with 88 additions and 100 deletions

View File

@ -10,9 +10,10 @@ import (
"encoding/binary"
"errors"
"io"
"io/ioutil"
"log"
"sync"
"github.com/klauspost/compress/zstd"
)
// Error returned if a Producer has run to its end.
@ -100,88 +101,102 @@ func NewDecodedBlock(data []byte, colors *Colors) (db *DecodedBlock, err error)
version := data[0]
contentWidth := Min(int(data[2]), 2)
paramsWidth := Min(int(data[3]), 2)
uncompressedLen := nodeCount * (contentWidth + paramsWidth)
//var mapContent := make([]byte, uncompressedLen)
var mapContent []byte
var offset int
switch {
case version >= 27:
offset = 6
case version >= 22:
offset = 4
default:
offset = 2
}
zr := zlibReaderPool.Get().(interface {
io.ReadCloser
zlib.Resetter
})
defer func() {
zr.Close() // This sould not be necessary.
zlibReaderPool.Put(zr)
}()
if version >= 29 {
dec, err := zstd.NewReader(nil)
if err != nil {
return nil, err
}
mapContent, err = dec.DecodeAll(data[1:], nil)
if err != nil {
return nil, err
}
} else {
contentWidth := Min(int(data[2]), 2)
paramsWidth := Min(int(data[3]), 2)
buf := posBuf{Data: data[offset:]}
if err = zr.Reset(&buf, nil); err != nil {
return
}
uncompressedLen := nodeCount * (contentWidth + paramsWidth)
mapContent := make([]byte, uncompressedLen)
switch {
case version >= 27:
offset = 6
case version >= 22:
offset = 4
default:
offset = 2
}
var k int
k, err = io.ReadFull(zr, mapContent)
if err != nil {
return
}
zr := zlibReaderPool.Get().(interface {
io.ReadCloser
zlib.Resetter
})
defer func() {
zr.Close() // This sould not be necessary.
zlibReaderPool.Put(zr)
}()
if k != uncompressedLen {
err = ErrMapContentSizeMismatch
return
}
buf := posBuf{Data: data[offset:]}
if err = zr.Reset(&buf, nil); err != nil {
return
}
// There is a bug before Go 1.7 that enforces
// to add 4 as an offset after the compressed
// geometry data. This is resolved via build tags
// and definitions in pre17offset.go and
// post17offset.go.
offset += buf.Pos + afterCompressOfs
buf.Pos = 0
if offset >= dataLen {
return nil, ErrBlockTruncated
}
buf.Data = data[offset:]
mapContent = make([]byte, uncompressedLen)
if err = zr.(zlib.Resetter).Reset(&buf, nil); err != nil {
return
}
var k int
k, err = io.ReadFull(zr, mapContent)
if err != nil {
return
}
// Discard the meta data.
if _, err = io.Copy(ioutil.Discard, zr); err != nil {
return
}
if k != uncompressedLen {
err = ErrMapContentSizeMismatch
return
}
offset += buf.Pos
switch {
case version <= 21:
offset += 2
case version == 23:
offset++
case version == 24:
// There is a bug before Go 1.7 that enforces
// to add 4 as an offset after the compressed
// geometry data. This is resolved via build tags
// and definitions in pre17offset.go and
// post17offset.go.
offset += buf.Pos + afterCompressOfs
buf.Pos = 0
if offset >= dataLen {
return nil, ErrBlockTruncated
}
ver := data[offset]
offset++
if ver == 1 {
if offset+1 >= dataLen {
buf.Data = data[offset:]
if err = zr.(zlib.Resetter).Reset(&buf, nil); err != nil {
return
}
// Discard the meta data.
if _, err = io.Copy(io.Discard, zr); err != nil {
return
}
offset += buf.Pos
switch {
case version <= 21:
offset += 2
case version == 23:
offset++
case version == 24:
if offset >= dataLen {
return nil, ErrBlockTruncated
}
num := int(binary.BigEndian.Uint16(data[offset:]))
offset += 2 + 10*num
ver := data[offset]
offset++
if ver == 1 {
if offset+1 >= dataLen {
return nil, ErrBlockTruncated
}
num := int(binary.BigEndian.Uint16(data[offset:]))
offset += 2 + 10*num
}
}
}