github.com/bir3/gocompiler@v0.9.2202/extra/compress/zstd/fse_decoder.go (about)

     1  // Copyright 2019+ Klaus Post. All rights reserved.
     2  // License information can be found in the LICENSE file.
     3  // Based on work by Yann Collet, released under BSD License.
     4  
     5  package zstd
     6  
     7  import (
     8  	"encoding/binary"
     9  	"errors"
    10  	"fmt"
    11  	"io"
    12  )
    13  
    14  const (
    15  	tablelogAbsoluteMax = 9
    16  )
    17  
    18  const (
    19  	/*!MEMORY_USAGE :
    20  	 *  Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
    21  	 *  Increasing memory usage improves compression ratio
    22  	 *  Reduced memory usage can improve speed, due to cache effect
    23  	 *  Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */
    24  	maxMemoryUsage = tablelogAbsoluteMax + 2
    25  
    26  	maxTableLog    = maxMemoryUsage - 2
    27  	maxTablesize   = 1 << maxTableLog
    28  	maxTableMask   = (1 << maxTableLog) - 1
    29  	minTablelog    = 5
    30  	maxSymbolValue = 255
    31  )
    32  
    33  // fseDecoder provides temporary storage for compression and decompression.
    34  type fseDecoder struct {
    35  	dt             [maxTablesize]decSymbol // Decompression table.
    36  	symbolLen      uint16                  // Length of active part of the symbol table.
    37  	actualTableLog uint8                   // Selected tablelog.
    38  	maxBits        uint8                   // Maximum number of additional bits
    39  
    40  	// used for table creation to avoid allocations.
    41  	stateTable [256]uint16
    42  	norm       [maxSymbolValue + 1]int16
    43  	preDefined bool
    44  }
    45  
    46  // tableStep returns the next table index.
    47  func tableStep(tableSize uint32) uint32 {
    48  	return (tableSize >> 1) + (tableSize >> 3) + 3
    49  }
    50  
    51  // readNCount will read the symbol distribution so decoding tables can be constructed.
    52  func (s *fseDecoder) readNCount(b *byteReader, maxSymbol uint16) error {
    53  	var (
    54  		charnum   uint16
    55  		previous0 bool
    56  	)
    57  	if b.remain() < 4 {
    58  		return errors.New("input too small")
    59  	}
    60  	bitStream := b.Uint32NC()
    61  	nbBits := uint((bitStream & 0xF) + minTablelog) // extract tableLog
    62  	if nbBits > tablelogAbsoluteMax {
    63  		println("Invalid tablelog:", nbBits)
    64  		return errors.New("tableLog too large")
    65  	}
    66  	bitStream >>= 4
    67  	bitCount := uint(4)
    68  
    69  	s.actualTableLog = uint8(nbBits)
    70  	remaining := int32((1 << nbBits) + 1)
    71  	threshold := int32(1 << nbBits)
    72  	gotTotal := int32(0)
    73  	nbBits++
    74  
    75  	for remaining > 1 && charnum <= maxSymbol {
    76  		if previous0 {
    77  			//println("prev0")
    78  			n0 := charnum
    79  			for (bitStream & 0xFFFF) == 0xFFFF {
    80  				//println("24 x 0")
    81  				n0 += 24
    82  				if r := b.remain(); r > 5 {
    83  					b.advance(2)
    84  					// The check above should make sure we can read 32 bits
    85  					bitStream = b.Uint32NC() >> bitCount
    86  				} else {
    87  					// end of bit stream
    88  					bitStream >>= 16
    89  					bitCount += 16
    90  				}
    91  			}
    92  			//printf("bitstream: %d, 0b%b", bitStream&3, bitStream)
    93  			for (bitStream & 3) == 3 {
    94  				n0 += 3
    95  				bitStream >>= 2
    96  				bitCount += 2
    97  			}
    98  			n0 += uint16(bitStream & 3)
    99  			bitCount += 2
   100  
   101  			if n0 > maxSymbolValue {
   102  				return errors.New("maxSymbolValue too small")
   103  			}
   104  			//println("inserting ", n0-charnum, "zeroes from idx", charnum, "ending before", n0)
   105  			for charnum < n0 {
   106  				s.norm[uint8(charnum)] = 0
   107  				charnum++
   108  			}
   109  
   110  			if r := b.remain(); r >= 7 || r-int(bitCount>>3) >= 4 {
   111  				b.advance(bitCount >> 3)
   112  				bitCount &= 7
   113  				// The check above should make sure we can read 32 bits
   114  				bitStream = b.Uint32NC() >> bitCount
   115  			} else {
   116  				bitStream >>= 2
   117  			}
   118  		}
   119  
   120  		max := (2*threshold - 1) - remaining
   121  		var count int32
   122  
   123  		if int32(bitStream)&(threshold-1) < max {
   124  			count = int32(bitStream) & (threshold - 1)
   125  			if debugAsserts && nbBits < 1 {
   126  				panic("nbBits underflow")
   127  			}
   128  			bitCount += nbBits - 1
   129  		} else {
   130  			count = int32(bitStream) & (2*threshold - 1)
   131  			if count >= threshold {
   132  				count -= max
   133  			}
   134  			bitCount += nbBits
   135  		}
   136  
   137  		// extra accuracy
   138  		count--
   139  		if count < 0 {
   140  			// -1 means +1
   141  			remaining += count
   142  			gotTotal -= count
   143  		} else {
   144  			remaining -= count
   145  			gotTotal += count
   146  		}
   147  		s.norm[charnum&0xff] = int16(count)
   148  		charnum++
   149  		previous0 = count == 0
   150  		for remaining < threshold {
   151  			nbBits--
   152  			threshold >>= 1
   153  		}
   154  
   155  		if r := b.remain(); r >= 7 || r-int(bitCount>>3) >= 4 {
   156  			b.advance(bitCount >> 3)
   157  			bitCount &= 7
   158  			// The check above should make sure we can read 32 bits
   159  			bitStream = b.Uint32NC() >> (bitCount & 31)
   160  		} else {
   161  			bitCount -= (uint)(8 * (len(b.b) - 4 - b.off))
   162  			b.off = len(b.b) - 4
   163  			bitStream = b.Uint32() >> (bitCount & 31)
   164  		}
   165  	}
   166  	s.symbolLen = charnum
   167  	if s.symbolLen <= 1 {
   168  		return fmt.Errorf("symbolLen (%d) too small", s.symbolLen)
   169  	}
   170  	if s.symbolLen > maxSymbolValue+1 {
   171  		return fmt.Errorf("symbolLen (%d) too big", s.symbolLen)
   172  	}
   173  	if remaining != 1 {
   174  		return fmt.Errorf("corruption detected (remaining %d != 1)", remaining)
   175  	}
   176  	if bitCount > 32 {
   177  		return fmt.Errorf("corruption detected (bitCount %d > 32)", bitCount)
   178  	}
   179  	if gotTotal != 1<<s.actualTableLog {
   180  		return fmt.Errorf("corruption detected (total %d != %d)", gotTotal, 1<<s.actualTableLog)
   181  	}
   182  	b.advance((bitCount + 7) >> 3)
   183  	return s.buildDtable()
   184  }
   185  
   186  func (s *fseDecoder) mustReadFrom(r io.Reader) {
   187  	fatalErr := func(err error) {
   188  		if err != nil {
   189  			panic(err)
   190  		}
   191  	}
   192  	// 	dt             [maxTablesize]decSymbol // Decompression table.
   193  	//	symbolLen      uint16                  // Length of active part of the symbol table.
   194  	//	actualTableLog uint8                   // Selected tablelog.
   195  	//	maxBits        uint8                   // Maximum number of additional bits
   196  	//	// used for table creation to avoid allocations.
   197  	//	stateTable [256]uint16
   198  	//	norm       [maxSymbolValue + 1]int16
   199  	//	preDefined bool
   200  	fatalErr(binary.Read(r, binary.LittleEndian, &s.dt))
   201  	fatalErr(binary.Read(r, binary.LittleEndian, &s.symbolLen))
   202  	fatalErr(binary.Read(r, binary.LittleEndian, &s.actualTableLog))
   203  	fatalErr(binary.Read(r, binary.LittleEndian, &s.maxBits))
   204  	fatalErr(binary.Read(r, binary.LittleEndian, &s.stateTable))
   205  	fatalErr(binary.Read(r, binary.LittleEndian, &s.norm))
   206  	fatalErr(binary.Read(r, binary.LittleEndian, &s.preDefined))
   207  }
   208  
   209  // decSymbol contains information about a state entry,
   210  // Including the state offset base, the output symbol and
   211  // the number of bits to read for the low part of the destination state.
   212  // Using a composite uint64 is faster than a struct with separate members.
   213  type decSymbol uint64
   214  
   215  func newDecSymbol(nbits, addBits uint8, newState uint16, baseline uint32) decSymbol {
   216  	return decSymbol(nbits) | (decSymbol(addBits) << 8) | (decSymbol(newState) << 16) | (decSymbol(baseline) << 32)
   217  }
   218  
   219  func (d decSymbol) nbBits() uint8 {
   220  	return uint8(d)
   221  }
   222  
   223  func (d decSymbol) addBits() uint8 {
   224  	return uint8(d >> 8)
   225  }
   226  
   227  func (d decSymbol) newState() uint16 {
   228  	return uint16(d >> 16)
   229  }
   230  
   231  func (d decSymbol) baselineInt() int {
   232  	return int(d >> 32)
   233  }
   234  
   235  func (d *decSymbol) setNBits(nBits uint8) {
   236  	const mask = 0xffffffffffffff00
   237  	*d = (*d & mask) | decSymbol(nBits)
   238  }
   239  
   240  func (d *decSymbol) setAddBits(addBits uint8) {
   241  	const mask = 0xffffffffffff00ff
   242  	*d = (*d & mask) | (decSymbol(addBits) << 8)
   243  }
   244  
   245  func (d *decSymbol) setNewState(state uint16) {
   246  	const mask = 0xffffffff0000ffff
   247  	*d = (*d & mask) | decSymbol(state)<<16
   248  }
   249  
   250  func (d *decSymbol) setExt(addBits uint8, baseline uint32) {
   251  	const mask = 0xffff00ff
   252  	*d = (*d & mask) | (decSymbol(addBits) << 8) | (decSymbol(baseline) << 32)
   253  }
   254  
   255  // decSymbolValue returns the transformed decSymbol for the given symbol.
   256  func decSymbolValue(symb uint8, t []baseOffset) (decSymbol, error) {
   257  	if int(symb) >= len(t) {
   258  		return 0, fmt.Errorf("rle symbol %d >= max %d", symb, len(t))
   259  	}
   260  	lu := t[symb]
   261  	return newDecSymbol(0, lu.addBits, 0, lu.baseLine), nil
   262  }
   263  
   264  // setRLE will set the decoder til RLE mode.
   265  func (s *fseDecoder) setRLE(symbol decSymbol) {
   266  	s.actualTableLog = 0
   267  	s.maxBits = symbol.addBits()
   268  	s.dt[0] = symbol
   269  }
   270  
   271  // transform will transform the decoder table into a table usable for
   272  // decoding without having to apply the transformation while decoding.
   273  // The state will contain the base value and the number of bits to read.
   274  func (s *fseDecoder) transform(t []baseOffset) error {
   275  	tableSize := uint16(1 << s.actualTableLog)
   276  	s.maxBits = 0
   277  	for i, v := range s.dt[:tableSize] {
   278  		add := v.addBits()
   279  		if int(add) >= len(t) {
   280  			return fmt.Errorf("invalid decoding table entry %d, symbol %d >= max (%d)", i, v.addBits(), len(t))
   281  		}
   282  		lu := t[add]
   283  		if lu.addBits > s.maxBits {
   284  			s.maxBits = lu.addBits
   285  		}
   286  		v.setExt(lu.addBits, lu.baseLine)
   287  		s.dt[i] = v
   288  	}
   289  	return nil
   290  }
   291  
   292  type fseState struct {
   293  	dt    []decSymbol
   294  	state decSymbol
   295  }
   296  
   297  // Initialize and decodeAsync first state and symbol.
   298  func (s *fseState) init(br *bitReader, tableLog uint8, dt []decSymbol) {
   299  	s.dt = dt
   300  	br.fill()
   301  	s.state = dt[br.getBits(tableLog)]
   302  }
   303  
   304  // final returns the current state symbol without decoding the next.
   305  func (s decSymbol) final() (int, uint8) {
   306  	return s.baselineInt(), s.addBits()
   307  }