2018-11-09 13:54:47 +00:00
|
|
|
|
|
|
|
|
2018-11-11 16:44:30 +00:00
|
|
|
package archiver
|
2018-11-09 13:54:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
import "bytes"
|
|
|
|
import "compress/gzip"
|
|
|
|
import "fmt"
|
|
|
|
|
|
|
|
|
2021-11-17 17:50:30 +00:00
|
|
|
import "github.com/foobaz/go-zopfli/zopfli"
|
2021-11-17 19:07:28 +00:00
|
|
|
import "github.com/andybalholm/brotli"
|
2021-11-17 17:50:30 +00:00
|
|
|
|
|
|
|
|
2018-11-09 13:54:47 +00:00
|
|
|
|
|
|
|
|
2021-12-15 16:33:28 +00:00
|
|
|
func Compress (_data []byte, _algorithm string, _level int) ([]byte, error) {
|
2018-11-09 13:54:47 +00:00
|
|
|
switch _algorithm {
|
|
|
|
case "gz", "gzip" :
|
2021-12-15 16:33:28 +00:00
|
|
|
return CompressGzip (_data, _level)
|
2021-11-17 17:50:30 +00:00
|
|
|
case "zopfli" :
|
2021-12-15 16:33:28 +00:00
|
|
|
return CompressZopfli (_data, _level)
|
2018-11-09 13:54:47 +00:00
|
|
|
case "br", "brotli" :
|
2021-12-15 16:33:28 +00:00
|
|
|
return CompressBrotli (_data, _level)
|
2018-11-09 13:54:47 +00:00
|
|
|
case "", "none", "identity" :
|
2021-12-14 19:24:51 +00:00
|
|
|
return _data, nil
|
2018-11-09 13:54:47 +00:00
|
|
|
default :
|
2021-12-14 19:24:51 +00:00
|
|
|
return nil, fmt.Errorf ("[ea23f966] invalid compression algorithm `%s`", _algorithm)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func CompressEncoding (_algorithm string) (string, string, error) {
|
|
|
|
switch _algorithm {
|
|
|
|
case "gz", "gzip" :
|
|
|
|
return "gzip", "gzip", nil
|
|
|
|
case "zopfli" :
|
|
|
|
return "zopfli", "gzip", nil
|
|
|
|
case "br", "brotli" :
|
|
|
|
return "brotli", "br", nil
|
|
|
|
case "", "none", "identity" :
|
|
|
|
return "identity", "identity", nil
|
|
|
|
default :
|
|
|
|
return "", "", fmt.Errorf ("[6026a403] invalid compression algorithm `%s`", _algorithm)
|
2018-11-09 13:54:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-12-15 16:33:28 +00:00
|
|
|
func CompressGzip (_data []byte, _level int) ([]byte, error) {
|
2018-11-09 13:54:47 +00:00
|
|
|
|
|
|
|
_buffer := & bytes.Buffer {}
|
|
|
|
|
2021-12-15 16:33:28 +00:00
|
|
|
if (_level < -2) || (_level > 9) {
|
|
|
|
return nil, fmt.Errorf ("[a6c02c58] invalid compression level `%d` (-1 for default, -2 for Huffman only, 0 to 9 for fast to slow)", _level)
|
|
|
|
}
|
|
|
|
|
2018-11-09 13:54:47 +00:00
|
|
|
var _encoder *gzip.Writer
|
2021-12-15 16:33:28 +00:00
|
|
|
if _encoder_0, _error := gzip.NewWriterLevel (_buffer, _level); _error == nil {
|
2018-11-09 13:54:47 +00:00
|
|
|
_encoder = _encoder_0
|
|
|
|
} else {
|
2021-12-14 19:24:51 +00:00
|
|
|
return nil, _error
|
2018-11-09 13:54:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if _, _error := _encoder.Write (_data); _error != nil {
|
2021-12-14 19:24:51 +00:00
|
|
|
return nil, _error
|
2018-11-09 13:54:47 +00:00
|
|
|
}
|
|
|
|
if _error := _encoder.Close (); _error != nil {
|
2021-12-14 19:24:51 +00:00
|
|
|
return nil, _error
|
2018-11-09 13:54:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_data = _buffer.Bytes ()
|
2021-12-14 19:24:51 +00:00
|
|
|
return _data, nil
|
2018-11-09 13:54:47 +00:00
|
|
|
}
|
|
|
|
|
2021-11-17 17:50:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2021-12-15 16:33:28 +00:00
|
|
|
func CompressZopfli (_data []byte, _level int) ([]byte, error) {
|
|
|
|
|
|
|
|
if (_level < -1) || (_level > 30) {
|
|
|
|
return nil, fmt.Errorf ("[fe30ea07] invalid compression level `%d` (-1 for default, 0 to 30 iterations for fast to slow)", _level)
|
|
|
|
}
|
2021-11-17 17:50:30 +00:00
|
|
|
|
|
|
|
_buffer := & bytes.Buffer {}
|
|
|
|
|
|
|
|
_options := zopfli.DefaultOptions ()
|
2021-12-15 16:33:28 +00:00
|
|
|
if _level != -1 {
|
|
|
|
_options.NumIterations = _level
|
|
|
|
_options.BlockSplitting = true
|
|
|
|
_options.BlockSplittingLast = false
|
|
|
|
_options.BlockSplittingMax = 0
|
|
|
|
_options.BlockType = zopfli.DYNAMIC_BLOCK
|
|
|
|
}
|
2021-11-17 17:50:30 +00:00
|
|
|
|
|
|
|
if _error := zopfli.GzipCompress (&_options, _data, _buffer); _error != nil {
|
2021-12-14 19:24:51 +00:00
|
|
|
return nil, _error
|
2021-11-17 17:50:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_data = _buffer.Bytes ()
|
2021-12-14 19:24:51 +00:00
|
|
|
return _data, nil
|
2021-11-17 17:50:30 +00:00
|
|
|
}
|
|
|
|
|
2021-11-17 19:04:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2021-12-15 16:33:28 +00:00
|
|
|
func CompressBrotli (_data []byte, _level int) ([]byte, error) {
|
|
|
|
|
|
|
|
if (_level < -2) || (_level > 9) {
|
|
|
|
return nil, fmt.Errorf ("[4aa20d1b] invalid compression level `%d` (-1 for default, 0 to 9 for fast to slow, -2 for extreme)", _level)
|
|
|
|
}
|
2021-11-17 19:04:45 +00:00
|
|
|
|
|
|
|
_buffer := & bytes.Buffer {}
|
|
|
|
|
2021-12-15 16:33:28 +00:00
|
|
|
_options := brotli.WriterOptions {}
|
|
|
|
if _level == -2 {
|
|
|
|
_options.Quality = 11
|
|
|
|
_options.LGWin = 24
|
|
|
|
} else if _level == -1 {
|
|
|
|
_options.Quality = 6
|
|
|
|
} else {
|
|
|
|
_options.Quality = _level
|
|
|
|
}
|
2021-11-17 19:04:45 +00:00
|
|
|
|
2021-11-17 19:07:28 +00:00
|
|
|
_encoder := brotli.NewWriterOptions (_buffer, _options)
|
2021-11-17 19:04:45 +00:00
|
|
|
|
|
|
|
if _, _error := _encoder.Write (_data); _error != nil {
|
2021-12-14 19:24:51 +00:00
|
|
|
return nil, _error
|
2021-11-17 19:04:45 +00:00
|
|
|
}
|
|
|
|
if _error := _encoder.Close (); _error != nil {
|
2021-12-14 19:24:51 +00:00
|
|
|
return nil, _error
|
2021-11-17 19:04:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_data = _buffer.Bytes ()
|
2021-12-14 19:24:51 +00:00
|
|
|
return _data, nil
|
2021-11-17 19:04:45 +00:00
|
|
|
}
|
|
|
|
|