package huff0

import (
	
	
	
	

	
)

type dTable struct {
	single []dEntrySingle
}

// single-symbols decoding
type dEntrySingle struct {
	entry uint16
}

// Uses special code for all tables that are < 8 bits.
const use8BitTables = true

// ReadTable will read a table from the input.
// The size of the input may be larger than the table definition.
// Any content remaining after the table definition will be returned.
// If no Scratch is provided a new one is allocated.
// The returned Scratch can be used for encoding or decoding input using this table.
func ( []byte,  *Scratch) ( *Scratch,  []byte,  error) {
	,  = .prepare(nil)
	if  != nil {
		return , nil, 
	}
	if len() <= 1 {
		return , nil, errors.New("input too small for table")
	}
	 := [0]
	 = [1:]
	if  >= 128 {
		// Uncompressed
		 :=  - 127
		 = ( + 1) / 2
		if int() > len() {
			return , nil, errors.New("input too small for table")
		}
		for  := uint8(0);  < ;  += 2 {
			 := [/2]
			.huffWeight[] =  >> 4
			.huffWeight[+1] =  & 15
		}
		.symbolLen = uint16()
		 = [:]
	} else {
		if len() < int() {
			return , nil, fmt.Errorf("input too small for table, want %d bytes, have %d", , len())
		}
		// FSE compressed weights
		.fse.DecompressLimit = 255
		 := .huffWeight[:]
		.fse.Out = 
		,  := fse.Decompress([:], .fse)
		.fse.Out = nil
		if  != nil {
			return , nil, fmt.Errorf("fse decompress returned: %w", )
		}
		if len() > 255 {
			return , nil, errors.New("corrupt input: output table too large")
		}
		.symbolLen = uint16(len())
		 = [:]
	}

	// collect weight stats
	var  [16]uint32
	 := uint32(0)
	for ,  := range .huffWeight[:.symbolLen] {
		if  > tableLogMax {
			return , nil, errors.New("corrupt input: weight too large")
		}
		 :=  & 15
		[]++
		// (1 << (v2-1)) is slower since the compiler cannot prove that v2 isn't 0.
		 += (1 << ) >> 1
	}
	if  == 0 {
		return , nil, errors.New("corrupt input: weights zero")
	}

	// get last non-null symbol weight (implied, total must be 2^n)
	{
		 := highBit32() + 1
		if  > tableLogMax {
			return , nil, errors.New("corrupt input: tableLog too big")
		}
		.actualTableLog = uint8()
		// determine last weight
		{
			 := uint32(1) << 
			 :=  - 
			 := uint32(1) << highBit32()
			 := highBit32() + 1
			if  !=  {
				// last value must be a clean power of 2
				return , nil, errors.New("corrupt input: last value not power of two")
			}
			.huffWeight[.symbolLen] = uint8()
			.symbolLen++
			[]++
		}
	}

	if ([1] < 2) || ([1]&1 != 0) {
		// by construction : at least 2 elts of rank 1, must be even
		return , nil, errors.New("corrupt input: min elt size, even check failed ")
	}

	// TODO: Choose between single/double symbol decoding

	// Calculate starting value for each rank
	{
		var  uint32
		for  := uint8(1);  < .actualTableLog+1; ++ {
			 := 
			 += [] << ( - 1)
			[] = 
		}
	}

	// fill DTable (always full size)
	 := 1 << tableLogMax
	if len(.dt.single) !=  {
		.dt.single = make([]dEntrySingle, )
	}
	 := .prevTable
	if cap() < maxSymbolValue+1 {
		 = make([]cTableEntry, 0, maxSymbolValue+1)
	}
	 = [:maxSymbolValue+1]
	.prevTable = [:.symbolLen]
	.prevTableLog = .actualTableLog

	for ,  := range .huffWeight[:.symbolLen] {
		if  == 0 {
			[] = cTableEntry{
				val:   0,
				nBits: 0,
			}
			continue
		}
		 := (uint32(1) << ) >> 1
		 := dEntrySingle{
			entry: uint16(.actualTableLog+1-) | (uint16() << 8),
		}

		 := &[]
		[] = cTableEntry{
			val:   uint16(* >> ( - 1)),
			nBits: uint8(.entry),
		}

		 := .dt.single[* : *+]
		for  := range  {
			[] = 
		}
		* += 
	}

	return , , nil
}

// Decompress1X will decompress a 1X encoded stream.
// The length of the supplied input must match the end of a block exactly.
// Before this is called, the table must be initialized with ReadTable unless
// the encoder re-used the table.
// deprecated: Use the stateless Decoder() to get a concurrent version.
func ( *Scratch) ( []byte) ( []byte,  error) {
	if cap(.Out) < .MaxDecodedSize {
		.Out = make([]byte, .MaxDecodedSize)
	}
	.Out = .Out[:0:.MaxDecodedSize]
	.Out,  = .Decoder().Decompress1X(.Out, )
	return .Out, 
}

// Decompress4X will decompress a 4X encoded stream.
// Before this is called, the table must be initialized with ReadTable unless
// the encoder re-used the table.
// The length of the supplied input must match the end of a block exactly.
// The destination size of the uncompressed data must be known and provided.
// deprecated: Use the stateless Decoder() to get a concurrent version.
func ( *Scratch) ( []byte,  int) ( []byte,  error) {
	if  > .MaxDecodedSize {
		return nil, ErrMaxDecodedSizeExceeded
	}
	if cap(.Out) <  {
		.Out = make([]byte, .MaxDecodedSize)
	}
	.Out = .Out[:0:]
	.Out,  = .Decoder().Decompress4X(.Out, )
	return .Out, 
}

// Decoder will return a stateless decoder that can be used by multiple
// decompressors concurrently.
// Before this is called, the table must be initialized with ReadTable.
// The Decoder is still linked to the scratch buffer so that cannot be reused.
// However, it is safe to discard the scratch.
func ( *Scratch) () *Decoder {
	return &Decoder{
		dt:             .dt,
		actualTableLog: .actualTableLog,
		bufs:           &.decPool,
	}
}

// Decoder provides stateless decoding.
type Decoder struct {
	dt             dTable
	actualTableLog uint8
	bufs           *sync.Pool
}

func ( *Decoder) () *[4][256]byte {
	,  := .bufs.Get().(*[4][256]byte)
	if  {
		return 
	}
	return &[4][256]byte{}
}

// decompress1X8Bit will decompress a 1X encoded stream with tablelog <= 8.
// The cap of the output buffer will be the maximum decompressed size.
// The length of the supplied input must match the end of a block exactly.
func ( *Decoder) (,  []byte) ([]byte, error) {
	if .actualTableLog == 8 {
		return .decompress1X8BitExactly(, )
	}
	var  bitReaderBytes
	 := .init()
	if  != nil {
		return , 
	}
	 := cap()
	 = [:0]

	// Avoid bounds check by always having full sized table.
	 := .dt.single[:256]

	// Use temp table to avoid bound checks/append penalty.
	 := .buffer()
	 := &[0]
	var  uint8

	switch .actualTableLog {
	case 8:
		const  = 0
		for .off >= 4 {
			.fillFast()
			 := [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+0] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+1] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+2] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+3] = uint8(.entry >> 8)

			 += 4
			if  == 0 {
				if len()+256 >  {
					.close()
					.bufs.Put()
					return nil, ErrMaxDecodedSizeExceeded
				}
				 = append(, [:]...)
			}
		}
	case 7:
		const  = 8 - 7
		for .off >= 4 {
			.fillFast()
			 := [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+0] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+1] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+2] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+3] = uint8(.entry >> 8)

			 += 4
			if  == 0 {
				if len()+256 >  {
					.close()
					.bufs.Put()
					return nil, ErrMaxDecodedSizeExceeded
				}
				 = append(, [:]...)
			}
		}
	case 6:
		const  = 8 - 6
		for .off >= 4 {
			.fillFast()
			 := [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+0] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+1] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+2] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+3] = uint8(.entry >> 8)

			 += 4
			if  == 0 {
				if len()+256 >  {
					.bufs.Put()
					.close()
					return nil, ErrMaxDecodedSizeExceeded
				}
				 = append(, [:]...)
			}
		}
	case 5:
		const  = 8 - 5
		for .off >= 4 {
			.fillFast()
			 := [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+0] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+1] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+2] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+3] = uint8(.entry >> 8)

			 += 4
			if  == 0 {
				if len()+256 >  {
					.bufs.Put()
					.close()
					return nil, ErrMaxDecodedSizeExceeded
				}
				 = append(, [:]...)
			}
		}
	case 4:
		const  = 8 - 4
		for .off >= 4 {
			.fillFast()
			 := [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+0] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+1] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+2] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+3] = uint8(.entry >> 8)

			 += 4
			if  == 0 {
				if len()+256 >  {
					.bufs.Put()
					.close()
					return nil, ErrMaxDecodedSizeExceeded
				}
				 = append(, [:]...)
			}
		}
	case 3:
		const  = 8 - 3
		for .off >= 4 {
			.fillFast()
			 := [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+0] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+1] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+2] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+3] = uint8(.entry >> 8)

			 += 4
			if  == 0 {
				if len()+256 >  {
					.bufs.Put()
					.close()
					return nil, ErrMaxDecodedSizeExceeded
				}
				 = append(, [:]...)
			}
		}
	case 2:
		const  = 8 - 2
		for .off >= 4 {
			.fillFast()
			 := [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+0] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+1] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+2] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+3] = uint8(.entry >> 8)

			 += 4
			if  == 0 {
				if len()+256 >  {
					.bufs.Put()
					.close()
					return nil, ErrMaxDecodedSizeExceeded
				}
				 = append(, [:]...)
			}
		}
	case 1:
		const  = 8 - 1
		for .off >= 4 {
			.fillFast()
			 := [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+0] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+1] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+2] = uint8(.entry >> 8)

			 = [uint8(.value>>(56+))]
			.advance(uint8(.entry))
			[+3] = uint8(.entry >> 8)

			 += 4
			if  == 0 {
				if len()+256 >  {
					.bufs.Put()
					.close()
					return nil, ErrMaxDecodedSizeExceeded
				}
				 = append(, [:]...)
			}
		}
	default:
		.bufs.Put()
		return nil, fmt.Errorf("invalid tablelog: %d", .actualTableLog)
	}

	if len()+int() >  {
		.bufs.Put()
		.close()
		return nil, ErrMaxDecodedSizeExceeded
	}
	 = append(, [:]...)

	// br < 4, so uint8 is fine
	 := int8(uint8(.off)*8 + (64 - .bitsRead))
	 := (8 - .actualTableLog) & 7

	for  > 0 {
		if .bitsRead >= 64-8 {
			for .off > 0 {
				.value |= uint64(.in[.off-1]) << (.bitsRead - 8)
				.bitsRead -= 8
				.off--
			}
		}
		if len() >=  {
			.close()
			.bufs.Put()
			return nil, ErrMaxDecodedSizeExceeded
		}
		 := [.peekByteFast()>>]
		 := uint8(.entry)
		.advance()
		 -= int8()
		 = append(, uint8(.entry>>8))
	}
	.bufs.Put()
	return , .close()
}

// decompress1X8Bit will decompress a 1X encoded stream with tablelog <= 8.
// The cap of the output buffer will be the maximum decompressed size.
// The length of the supplied input must match the end of a block exactly.
func ( *Decoder) (,  []byte) ([]byte, error) {
	var  bitReaderBytes
	 := .init()
	if  != nil {
		return , 
	}
	 := cap()
	 = [:0]

	// Avoid bounds check by always having full sized table.
	 := .dt.single[:256]

	// Use temp table to avoid bound checks/append penalty.
	 := .buffer()
	 := &[0]
	var  uint8

	const  = 56

	//fmt.Printf("mask: %b, tl:%d\n", mask, d.actualTableLog)
	for .off >= 4 {
		.fillFast()
		 := [uint8(.value>>)]
		.advance(uint8(.entry))
		[+0] = uint8(.entry >> 8)

		 = [uint8(.value>>)]
		.advance(uint8(.entry))
		[+1] = uint8(.entry >> 8)

		 = [uint8(.value>>)]
		.advance(uint8(.entry))
		[+2] = uint8(.entry >> 8)

		 = [uint8(.value>>)]
		.advance(uint8(.entry))
		[+3] = uint8(.entry >> 8)

		 += 4
		if  == 0 {
			if len()+256 >  {
				.bufs.Put()
				.close()
				return nil, ErrMaxDecodedSizeExceeded
			}
			 = append(, [:]...)
		}
	}

	if len()+int() >  {
		.bufs.Put()
		.close()
		return nil, ErrMaxDecodedSizeExceeded
	}
	 = append(, [:]...)

	// br < 4, so uint8 is fine
	 := int8(uint8(.off)*8 + (64 - .bitsRead))
	for  > 0 {
		if .bitsRead >= 64-8 {
			for .off > 0 {
				.value |= uint64(.in[.off-1]) << (.bitsRead - 8)
				.bitsRead -= 8
				.off--
			}
		}
		if len() >=  {
			.bufs.Put()
			.close()
			return nil, ErrMaxDecodedSizeExceeded
		}
		 := [.peekByteFast()]
		 := uint8(.entry)
		.advance()
		 -= int8()
		 = append(, uint8(.entry>>8))
	}
	.bufs.Put()
	return , .close()
}

// Decompress4X will decompress a 4X encoded stream.
// The length of the supplied input must match the end of a block exactly.
// The *capacity* of the dst slice must match the destination size of
// the uncompressed data exactly.
func ( *Decoder) (,  []byte) ([]byte, error) {
	if .actualTableLog == 8 {
		return .decompress4X8bitExactly(, )
	}

	var  [4]bitReaderBytes
	 := 6
	for  := 0;  < 3; ++ {
		 := int([*2]) | (int([*2+1]) << 8)
		if + >= len() {
			return nil, errors.New("truncated input (or invalid offset)")
		}
		 := [].init([ : +])
		if  != nil {
			return nil, 
		}
		 += 
	}
	 := [3].init([:])
	if  != nil {
		return nil, 
	}

	// destination, offset to match first output
	 := cap()
	 = [:]
	 := 
	 := ( + 3) / 4

	 := (56 + (8 - .actualTableLog)) & 63

	const  = 1 << 8
	 := .dt.single[:]

	// Use temp table to avoid bound checks/append penalty.
	 := .buffer()
	var  uint8
	var  int

	// Decode 4 values from each decoder/loop.
	const  = 256
	for {
		if [0].off < 4 || [1].off < 4 || [2].off < 4 || [3].off < 4 {
			break
		}

		{
			// Interleave 2 decodes.
			const  = 0
			const  = 1
			 := &[]
			 := &[]
			.fillFast()
			.fillFast()

			 := [uint8(.value>>)].entry
			 := [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][] = uint8( >> 8)
			[][] = uint8( >> 8)

			 = [uint8(.value>>)].entry
			 = [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][+1] = uint8( >> 8)
			[][+1] = uint8( >> 8)

			 = [uint8(.value>>)].entry
			 = [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][+2] = uint8( >> 8)
			[][+2] = uint8( >> 8)

			 = [uint8(.value>>)].entry
			 = [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][+3] = uint8( >> 8)
			[][+3] = uint8( >> 8)
		}

		{
			const  = 2
			const  = 3
			 := &[]
			 := &[]
			.fillFast()
			.fillFast()

			 := [uint8(.value>>)].entry
			 := [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][] = uint8( >> 8)
			[][] = uint8( >> 8)

			 = [uint8(.value>>)].entry
			 = [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][+1] = uint8( >> 8)
			[][+1] = uint8( >> 8)

			 = [uint8(.value>>)].entry
			 = [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][+2] = uint8( >> 8)
			[][+2] = uint8( >> 8)

			 = [uint8(.value>>)].entry
			 = [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][+3] = uint8( >> 8)
			[][+3] = uint8( >> 8)
		}

		 += 4

		if  == 0 {
			if  >  {
				.bufs.Put()
				return nil, errors.New("corruption detected: stream overrun 1")
			}
			// There must at least be 3 buffers left.
			if len()- < *3 {
				.bufs.Put()
				return nil, errors.New("corruption detected: stream overrun 2")
			}
			//copy(out, buf[0][:])
			//copy(out[dstEvery:], buf[1][:])
			//copy(out[dstEvery*2:], buf[2][:])
			*(*[]byte)() = [0]
			*(*[]byte)([:]) = [1]
			*(*[]byte)([*2:]) = [2]
			*(*[]byte)([*3:]) = [3]
			 = [:]
			 +=  * 4
		}
	}
	if  > 0 {
		 := int()
		if len() < *3+ {
			.bufs.Put()
			return nil, errors.New("corruption detected: stream overrun 3")
		}
		copy(, [0][:])
		copy([:], [1][:])
		copy([*2:], [2][:])
		copy([*3:], [3][:])
		 += int() * 4
		 = [:]
	}

	// Decode remaining.
	// Decode remaining.
	 :=  - ( / 4)
	for  := range  {
		 :=  * 
		 :=  + 
		if  > len() {
			 = len()
		}
		 := &[]
		 := .remaining()
		for  > 0 {
			if .finished() {
				.bufs.Put()
				return nil, io.ErrUnexpectedEOF
			}
			if .bitsRead >= 56 {
				if .off >= 4 {
					 := .in[.off-4:]
					 = [:4]
					 := (uint32([0])) | (uint32([1]) << 8) | (uint32([2]) << 16) | (uint32([3]) << 24)
					.value |= uint64() << (.bitsRead - 32)
					.bitsRead -= 32
					.off -= 4
				} else {
					for .off > 0 {
						.value |= uint64(.in[.off-1]) << (.bitsRead - 8)
						.bitsRead -= 8
						.off--
					}
				}
			}
			// end inline...
			if  >=  {
				.bufs.Put()
				return nil, errors.New("corruption detected: stream overrun 4")
			}

			// Read value and increment offset.
			 := [uint8(.value>>)].entry
			 := uint8()
			.advance()
			 -= uint()
			[] = uint8( >> 8)
			++
		}
		if  !=  {
			.bufs.Put()
			return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", , , )
		}
		 +=  - *
		 = .close()
		if  != nil {
			.bufs.Put()
			return nil, 
		}
	}
	.bufs.Put()
	if  !=  {
		return nil, errors.New("corruption detected: short output block")
	}
	return , nil
}

// Decompress4X will decompress a 4X encoded stream.
// The length of the supplied input must match the end of a block exactly.
// The *capacity* of the dst slice must match the destination size of
// the uncompressed data exactly.
func ( *Decoder) (,  []byte) ([]byte, error) {
	var  [4]bitReaderBytes
	 := 6
	for  := 0;  < 3; ++ {
		 := int([*2]) | (int([*2+1]) << 8)
		if + >= len() {
			return nil, errors.New("truncated input (or invalid offset)")
		}
		 := [].init([ : +])
		if  != nil {
			return nil, 
		}
		 += 
	}
	 := [3].init([:])
	if  != nil {
		return nil, 
	}

	// destination, offset to match first output
	 := cap()
	 = [:]
	 := 
	 := ( + 3) / 4

	const  = 56
	const  = 1 << 8
	 := .dt.single[:]

	// Use temp table to avoid bound checks/append penalty.
	 := .buffer()
	var  uint8
	var  int

	// Decode 4 values from each decoder/loop.
	const  = 256
	for {
		if [0].off < 4 || [1].off < 4 || [2].off < 4 || [3].off < 4 {
			break
		}

		{
			// Interleave 2 decodes.
			const  = 0
			const  = 1
			 := &[]
			 := &[]
			.fillFast()
			.fillFast()

			 := [uint8(.value>>)].entry
			 := [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][] = uint8( >> 8)
			[][] = uint8( >> 8)

			 = [uint8(.value>>)].entry
			 = [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][+1] = uint8( >> 8)
			[][+1] = uint8( >> 8)

			 = [uint8(.value>>)].entry
			 = [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][+2] = uint8( >> 8)
			[][+2] = uint8( >> 8)

			 = [uint8(.value>>)].entry
			 = [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][+3] = uint8( >> 8)
			[][+3] = uint8( >> 8)
		}

		{
			const  = 2
			const  = 3
			 := &[]
			 := &[]
			.fillFast()
			.fillFast()

			 := [uint8(.value>>)].entry
			 := [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][] = uint8( >> 8)
			[][] = uint8( >> 8)

			 = [uint8(.value>>)].entry
			 = [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][+1] = uint8( >> 8)
			[][+1] = uint8( >> 8)

			 = [uint8(.value>>)].entry
			 = [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][+2] = uint8( >> 8)
			[][+2] = uint8( >> 8)

			 = [uint8(.value>>)].entry
			 = [uint8(.value>>)].entry
			.bitsRead += uint8()
			.value <<=  & 63
			.bitsRead += uint8()
			.value <<=  & 63
			[][+3] = uint8( >> 8)
			[][+3] = uint8( >> 8)
		}

		 += 4

		if  == 0 {
			if  >  {
				.bufs.Put()
				return nil, errors.New("corruption detected: stream overrun 1")
			}
			// There must at least be 3 buffers left.
			if len()- < *3 {
				.bufs.Put()
				return nil, errors.New("corruption detected: stream overrun 2")
			}

			//copy(out, buf[0][:])
			//copy(out[dstEvery:], buf[1][:])
			//copy(out[dstEvery*2:], buf[2][:])
			// copy(out[dstEvery*3:], buf[3][:])
			*(*[]byte)() = [0]
			*(*[]byte)([:]) = [1]
			*(*[]byte)([*2:]) = [2]
			*(*[]byte)([*3:]) = [3]
			 = [:]
			 +=  * 4
		}
	}
	if  > 0 {
		 := int()
		if len() < *3+ {
			return nil, errors.New("corruption detected: stream overrun 3")
		}
		copy(, [0][:])
		copy([:], [1][:])
		copy([*2:], [2][:])
		copy([*3:], [3][:])
		 += int() * 4
		 = [:]
	}

	// Decode remaining.
	 :=  - ( / 4)
	for  := range  {
		 :=  * 
		 :=  + 
		if  > len() {
			 = len()
		}
		 := &[]
		 := .remaining()
		for  > 0 {
			if .finished() {
				.bufs.Put()
				return nil, io.ErrUnexpectedEOF
			}
			if .bitsRead >= 56 {
				if .off >= 4 {
					 := .in[.off-4:]
					 = [:4]
					 := (uint32([0])) | (uint32([1]) << 8) | (uint32([2]) << 16) | (uint32([3]) << 24)
					.value |= uint64() << (.bitsRead - 32)
					.bitsRead -= 32
					.off -= 4
				} else {
					for .off > 0 {
						.value |= uint64(.in[.off-1]) << (.bitsRead - 8)
						.bitsRead -= 8
						.off--
					}
				}
			}
			// end inline...
			if  >=  {
				.bufs.Put()
				return nil, errors.New("corruption detected: stream overrun 4")
			}

			// Read value and increment offset.
			 := [.peekByteFast()].entry
			 := uint8()
			.advance()
			 -= uint()
			[] = uint8( >> 8)
			++
		}
		if  !=  {
			.bufs.Put()
			return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", , , )
		}

		 +=  - *
		 = .close()
		if  != nil {
			.bufs.Put()
			return nil, 
		}
	}
	.bufs.Put()
	if  !=  {
		return nil, errors.New("corruption detected: short output block")
	}
	return , nil
}

// matches will compare a decoding table to a coding table.
// Errors are written to the writer.
// Nothing will be written if table is ok.
func ( *Scratch) ( cTable,  io.Writer) {
	if  == nil || len(.dt.single) == 0 {
		return
	}
	 := .dt.single[:1<<.actualTableLog]
	 := .actualTableLog
	 := 0
	 := 0
	for ,  := range  {
		 := 0
		++
		if .nBits == 0 {
			for ,  := range  {
				if uint8(.entry>>8) == byte() {
					fmt.Fprintf(, "symbol %x has decoder, but no encoder\n", )
					++
					break
				}
			}
			if  == 0 {
				--
			}
			continue
		}
		// Unused bits in input
		 :=  - .nBits
		 := .val << 
		// decoder looks at top bits.
		 := []
		if uint8(.entry) != .nBits {
			fmt.Fprintf(, "symbol 0x%x bit size mismatch (enc: %d, dec:%d).\n", , .nBits, uint8(.entry))
			++
		}
		if uint8(.entry>>8) != uint8() {
			fmt.Fprintf(, "symbol 0x%x decoder output mismatch (enc: %d, dec:%d).\n", , , uint8(.entry>>8))
			++
		}
		if  > 0 {
			fmt.Fprintf(, "%d errors in base, stopping\n", )
			continue
		}
		// Ensure that all combinations are covered.
		for  := uint16(0);  < (1 << ); ++ {
			 :=  | 
			 := []
			if uint8(.entry) != .nBits {
				fmt.Fprintf(, "symbol 0x%x bit size mismatch (enc: %d, dec:%d).\n", , .nBits, uint8(.entry))
				++
			}
			if uint8(.entry>>8) != uint8() {
				fmt.Fprintf(, "symbol 0x%x decoder output mismatch (enc: %d, dec:%d).\n", , , uint8(.entry>>8))
				++
			}
			if  > 20 {
				fmt.Fprintf(, "%d errors, stopping\n", )
				break
			}
		}
		if  == 0 {
			++
			--
		}
	}
	if  > 0 {
		fmt.Fprintf(, "%d broken, %d ok\n", , )
	}
}