mirror of
https://github.com/containers/skopeo.git
synced 2025-09-24 03:17:17 +00:00
Bump github.com/containers/image/v5 from 5.19.1 to 5.20.0
Bumps [github.com/containers/image/v5](https://github.com/containers/image) from 5.19.1 to 5.20.0. - [Release notes](https://github.com/containers/image/releases) - [Commits](https://github.com/containers/image/compare/v5.19.1...v5.20.0) --- updated-dependencies: - dependency-name: github.com/containers/image/v5 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
166
vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go
generated
vendored
166
vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go
generated
vendored
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -24,6 +25,10 @@ const (
|
||||
codegenCodeCount = 19
|
||||
badCode = 255
|
||||
|
||||
// maxPredefinedTokens is the maximum number of tokens
|
||||
// where we check if fixed size is smaller.
|
||||
maxPredefinedTokens = 250
|
||||
|
||||
// bufferFlushSize indicates the buffer size
|
||||
// after which bytes are flushed to the writer.
|
||||
// Should preferably be a multiple of 6, since
|
||||
@@ -36,8 +41,11 @@ const (
|
||||
bufferSize = bufferFlushSize + 8
|
||||
)
|
||||
|
||||
// Minimum length code that emits bits.
|
||||
const lengthExtraBitsMinCode = 8
|
||||
|
||||
// The number of extra bits needed by length code X - LENGTH_CODES_START.
|
||||
var lengthExtraBits = [32]int8{
|
||||
var lengthExtraBits = [32]uint8{
|
||||
/* 257 */ 0, 0, 0,
|
||||
/* 260 */ 0, 0, 0, 0, 0, 1, 1, 1, 1, 2,
|
||||
/* 270 */ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
|
||||
@@ -51,6 +59,9 @@ var lengthBase = [32]uint8{
|
||||
64, 80, 96, 112, 128, 160, 192, 224, 255,
|
||||
}
|
||||
|
||||
// Minimum offset code that emits bits.
|
||||
const offsetExtraBitsMinCode = 4
|
||||
|
||||
// offset code word extra bits.
|
||||
var offsetExtraBits = [32]int8{
|
||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
|
||||
@@ -78,10 +89,10 @@ func init() {
|
||||
|
||||
for i := range offsetCombined[:] {
|
||||
// Don't use extended window values...
|
||||
if offsetBase[i] > 0x006000 {
|
||||
if offsetExtraBits[i] == 0 || offsetBase[i] > 0x006000 {
|
||||
continue
|
||||
}
|
||||
offsetCombined[i] = uint32(offsetExtraBits[i])<<16 | (offsetBase[i])
|
||||
offsetCombined[i] = uint32(offsetExtraBits[i]) | (offsetBase[i] << 8)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +108,7 @@ type huffmanBitWriter struct {
|
||||
// Data waiting to be written is bytes[0:nbytes]
|
||||
// and then the low nbits of bits.
|
||||
bits uint64
|
||||
nbits uint16
|
||||
nbits uint8
|
||||
nbytes uint8
|
||||
lastHuffMan bool
|
||||
literalEncoding *huffmanEncoder
|
||||
@@ -215,7 +226,7 @@ func (w *huffmanBitWriter) write(b []byte) {
|
||||
_, w.err = w.writer.Write(b)
|
||||
}
|
||||
|
||||
func (w *huffmanBitWriter) writeBits(b int32, nb uint16) {
|
||||
func (w *huffmanBitWriter) writeBits(b int32, nb uint8) {
|
||||
w.bits |= uint64(b) << (w.nbits & 63)
|
||||
w.nbits += nb
|
||||
if w.nbits >= 48 {
|
||||
@@ -571,7 +582,10 @@ func (w *huffmanBitWriter) writeBlock(tokens *tokens, eof bool, input []byte) {
|
||||
// Fixed Huffman baseline.
|
||||
var literalEncoding = fixedLiteralEncoding
|
||||
var offsetEncoding = fixedOffsetEncoding
|
||||
var size = w.fixedSize(extraBits)
|
||||
var size = math.MaxInt32
|
||||
if tokens.n < maxPredefinedTokens {
|
||||
size = w.fixedSize(extraBits)
|
||||
}
|
||||
|
||||
// Dynamic Huffman?
|
||||
var numCodegens int
|
||||
@@ -672,19 +686,21 @@ func (w *huffmanBitWriter) writeBlockDynamic(tokens *tokens, eof bool, input []b
|
||||
size = reuseSize
|
||||
}
|
||||
|
||||
if preSize := w.fixedSize(extraBits) + 7; usePrefs && preSize < size {
|
||||
// Check if we get a reasonable size decrease.
|
||||
if storable && ssize <= size {
|
||||
w.writeStoredHeader(len(input), eof)
|
||||
w.writeBytes(input)
|
||||
if tokens.n < maxPredefinedTokens {
|
||||
if preSize := w.fixedSize(extraBits) + 7; usePrefs && preSize < size {
|
||||
// Check if we get a reasonable size decrease.
|
||||
if storable && ssize <= size {
|
||||
w.writeStoredHeader(len(input), eof)
|
||||
w.writeBytes(input)
|
||||
return
|
||||
}
|
||||
w.writeFixedHeader(eof)
|
||||
if !sync {
|
||||
tokens.AddEOB()
|
||||
}
|
||||
w.writeTokens(tokens.Slice(), fixedLiteralEncoding.codes, fixedOffsetEncoding.codes)
|
||||
return
|
||||
}
|
||||
w.writeFixedHeader(eof)
|
||||
if !sync {
|
||||
tokens.AddEOB()
|
||||
}
|
||||
w.writeTokens(tokens.Slice(), fixedLiteralEncoding.codes, fixedOffsetEncoding.codes)
|
||||
return
|
||||
}
|
||||
// Check if we get a reasonable size decrease.
|
||||
if storable && ssize <= size {
|
||||
@@ -717,19 +733,21 @@ func (w *huffmanBitWriter) writeBlockDynamic(tokens *tokens, eof bool, input []b
|
||||
size, numCodegens = w.dynamicSize(w.literalEncoding, w.offsetEncoding, extraBits)
|
||||
|
||||
// Store predefined, if we don't get a reasonable improvement.
|
||||
if preSize := w.fixedSize(extraBits); usePrefs && preSize <= size {
|
||||
// Store bytes, if we don't get an improvement.
|
||||
if storable && ssize <= preSize {
|
||||
w.writeStoredHeader(len(input), eof)
|
||||
w.writeBytes(input)
|
||||
if tokens.n < maxPredefinedTokens {
|
||||
if preSize := w.fixedSize(extraBits); usePrefs && preSize <= size {
|
||||
// Store bytes, if we don't get an improvement.
|
||||
if storable && ssize <= preSize {
|
||||
w.writeStoredHeader(len(input), eof)
|
||||
w.writeBytes(input)
|
||||
return
|
||||
}
|
||||
w.writeFixedHeader(eof)
|
||||
if !sync {
|
||||
tokens.AddEOB()
|
||||
}
|
||||
w.writeTokens(tokens.Slice(), fixedLiteralEncoding.codes, fixedOffsetEncoding.codes)
|
||||
return
|
||||
}
|
||||
w.writeFixedHeader(eof)
|
||||
if !sync {
|
||||
tokens.AddEOB()
|
||||
}
|
||||
w.writeTokens(tokens.Slice(), fixedLiteralEncoding.codes, fixedOffsetEncoding.codes)
|
||||
return
|
||||
}
|
||||
|
||||
if storable && ssize <= size {
|
||||
@@ -833,9 +851,9 @@ func (w *huffmanBitWriter) writeTokens(tokens []token, leCodes, oeCodes []hcode)
|
||||
bits, nbits, nbytes := w.bits, w.nbits, w.nbytes
|
||||
|
||||
for _, t := range tokens {
|
||||
if t < matchType {
|
||||
if t < 256 {
|
||||
//w.writeCode(lits[t.literal()])
|
||||
c := lits[t.literal()]
|
||||
c := lits[t]
|
||||
bits |= uint64(c.code) << (nbits & 63)
|
||||
nbits += c.len
|
||||
if nbits >= 48 {
|
||||
@@ -858,12 +876,12 @@ func (w *huffmanBitWriter) writeTokens(tokens []token, leCodes, oeCodes []hcode)
|
||||
|
||||
// Write the length
|
||||
length := t.length()
|
||||
lengthCode := lengthCode(length)
|
||||
lengthCode := lengthCode(length) & 31
|
||||
if false {
|
||||
w.writeCode(lengths[lengthCode&31])
|
||||
w.writeCode(lengths[lengthCode])
|
||||
} else {
|
||||
// inlined
|
||||
c := lengths[lengthCode&31]
|
||||
c := lengths[lengthCode]
|
||||
bits |= uint64(c.code) << (nbits & 63)
|
||||
nbits += c.len
|
||||
if nbits >= 48 {
|
||||
@@ -883,10 +901,10 @@ func (w *huffmanBitWriter) writeTokens(tokens []token, leCodes, oeCodes []hcode)
|
||||
}
|
||||
}
|
||||
|
||||
extraLengthBits := uint16(lengthExtraBits[lengthCode&31])
|
||||
if extraLengthBits > 0 {
|
||||
if lengthCode >= lengthExtraBitsMinCode {
|
||||
extraLengthBits := lengthExtraBits[lengthCode]
|
||||
//w.writeBits(extraLength, extraLengthBits)
|
||||
extraLength := int32(length - lengthBase[lengthCode&31])
|
||||
extraLength := int32(length - lengthBase[lengthCode])
|
||||
bits |= uint64(extraLength) << (nbits & 63)
|
||||
nbits += extraLengthBits
|
||||
if nbits >= 48 {
|
||||
@@ -907,10 +925,9 @@ func (w *huffmanBitWriter) writeTokens(tokens []token, leCodes, oeCodes []hcode)
|
||||
}
|
||||
// Write the offset
|
||||
offset := t.offset()
|
||||
offsetCode := offset >> 16
|
||||
offset &= matchOffsetOnlyMask
|
||||
offsetCode := (offset >> 16) & 31
|
||||
if false {
|
||||
w.writeCode(offs[offsetCode&31])
|
||||
w.writeCode(offs[offsetCode])
|
||||
} else {
|
||||
// inlined
|
||||
c := offs[offsetCode]
|
||||
@@ -932,11 +949,12 @@ func (w *huffmanBitWriter) writeTokens(tokens []token, leCodes, oeCodes []hcode)
|
||||
}
|
||||
}
|
||||
}
|
||||
offsetComb := offsetCombined[offsetCode]
|
||||
if offsetComb > 1<<16 {
|
||||
|
||||
if offsetCode >= offsetExtraBitsMinCode {
|
||||
offsetComb := offsetCombined[offsetCode]
|
||||
//w.writeBits(extraOffset, extraOffsetBits)
|
||||
bits |= uint64(offset-(offsetComb&0xffff)) << (nbits & 63)
|
||||
nbits += uint16(offsetComb >> 16)
|
||||
bits |= uint64((offset-(offsetComb>>8))&matchOffsetOnlyMask) << (nbits & 63)
|
||||
nbits += uint8(offsetComb)
|
||||
if nbits >= 48 {
|
||||
binary.LittleEndian.PutUint64(w.bytes[nbytes:], bits)
|
||||
//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits
|
||||
@@ -1002,6 +1020,29 @@ func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte, sync bool) {
|
||||
// https://stackoverflow.com/a/25454430
|
||||
const guessHeaderSizeBits = 70 * 8
|
||||
histogram(input, w.literalFreq[:numLiterals], fill)
|
||||
ssize, storable := w.storedSize(input)
|
||||
if storable && len(input) > 1024 {
|
||||
// Quick check for incompressible content.
|
||||
abs := float64(0)
|
||||
avg := float64(len(input)) / 256
|
||||
max := float64(len(input) * 2)
|
||||
for _, v := range w.literalFreq[:256] {
|
||||
diff := float64(v) - avg
|
||||
abs += diff * diff
|
||||
if abs > max {
|
||||
break
|
||||
}
|
||||
}
|
||||
if abs < max {
|
||||
if debugDeflate {
|
||||
fmt.Println("stored", abs, "<", max)
|
||||
}
|
||||
// No chance we can compress this...
|
||||
w.writeStoredHeader(len(input), eof)
|
||||
w.writeBytes(input)
|
||||
return
|
||||
}
|
||||
}
|
||||
w.literalFreq[endBlockMarker] = 1
|
||||
w.tmpLitEncoding.generate(w.literalFreq[:numLiterals], 15)
|
||||
if fill {
|
||||
@@ -1019,8 +1060,10 @@ func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte, sync bool) {
|
||||
estBits += estBits >> w.logNewTablePenalty
|
||||
|
||||
// Store bytes, if we don't get a reasonable improvement.
|
||||
ssize, storable := w.storedSize(input)
|
||||
if storable && ssize <= estBits {
|
||||
if debugDeflate {
|
||||
fmt.Println("stored,", ssize, "<=", estBits)
|
||||
}
|
||||
w.writeStoredHeader(len(input), eof)
|
||||
w.writeBytes(input)
|
||||
return
|
||||
@@ -1031,7 +1074,7 @@ func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte, sync bool) {
|
||||
|
||||
if estBits < reuseSize {
|
||||
if debugDeflate {
|
||||
//fmt.Println("not reusing, reuse:", reuseSize/8, "> new:", estBits/8, "- header est:", w.lastHeader/8)
|
||||
fmt.Println("NOT reusing, reuse:", reuseSize/8, "> new:", estBits/8, "header est:", w.lastHeader/8, "bytes")
|
||||
}
|
||||
// We owe an EOB
|
||||
w.writeCode(w.literalEncoding.codes[endBlockMarker])
|
||||
@@ -1065,6 +1108,9 @@ func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte, sync bool) {
|
||||
// Go 1.16 LOVES having these on stack. At least 1.5x the speed.
|
||||
bits, nbits, nbytes := w.bits, w.nbits, w.nbytes
|
||||
|
||||
if debugDeflate {
|
||||
count -= int(nbytes)*8 + int(nbits)
|
||||
}
|
||||
// Unroll, write 3 codes/loop.
|
||||
// Fastest number of unrolls.
|
||||
for len(input) > 3 {
|
||||
@@ -1074,13 +1120,16 @@ func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte, sync bool) {
|
||||
binary.LittleEndian.PutUint64(w.bytes[nbytes:], bits)
|
||||
bits >>= (n * 8) & 63
|
||||
nbits -= n * 8
|
||||
nbytes += uint8(n)
|
||||
nbytes += n
|
||||
}
|
||||
if nbytes >= bufferFlushSize {
|
||||
if w.err != nil {
|
||||
nbytes = 0
|
||||
return
|
||||
}
|
||||
if debugDeflate {
|
||||
count += int(nbytes) * 8
|
||||
}
|
||||
_, w.err = w.writer.Write(w.bytes[:nbytes])
|
||||
nbytes = 0
|
||||
}
|
||||
@@ -1096,13 +1145,6 @@ func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte, sync bool) {
|
||||
|
||||
// Remaining...
|
||||
for _, t := range input {
|
||||
// Bitwriting inlined, ~30% speedup
|
||||
c := encoding[t]
|
||||
bits |= uint64(c.code) << (nbits & 63)
|
||||
nbits += c.len
|
||||
if debugDeflate {
|
||||
count += int(c.len)
|
||||
}
|
||||
if nbits >= 48 {
|
||||
binary.LittleEndian.PutUint64(w.bytes[nbytes:], bits)
|
||||
//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits
|
||||
@@ -1114,17 +1156,33 @@ func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte, sync bool) {
|
||||
nbytes = 0
|
||||
return
|
||||
}
|
||||
if debugDeflate {
|
||||
count += int(nbytes) * 8
|
||||
}
|
||||
_, w.err = w.writer.Write(w.bytes[:nbytes])
|
||||
nbytes = 0
|
||||
}
|
||||
}
|
||||
// Bitwriting inlined, ~30% speedup
|
||||
c := encoding[t]
|
||||
bits |= uint64(c.code) << (nbits & 63)
|
||||
nbits += c.len
|
||||
if debugDeflate {
|
||||
count += int(c.len)
|
||||
}
|
||||
}
|
||||
// Restore...
|
||||
w.bits, w.nbits, w.nbytes = bits, nbits, nbytes
|
||||
|
||||
if debugDeflate {
|
||||
fmt.Println("wrote", count/8, "bytes")
|
||||
nb := count + int(nbytes)*8 + int(nbits)
|
||||
fmt.Println("wrote", nb, "bits,", nb/8, "bytes.")
|
||||
}
|
||||
// Flush if needed to have space.
|
||||
if w.nbits >= 48 {
|
||||
w.writeOutBits()
|
||||
}
|
||||
|
||||
if eof || sync {
|
||||
w.writeCode(w.literalEncoding.codes[endBlockMarker])
|
||||
w.lastHeader = 0
|
||||
|
Reference in New Issue
Block a user