mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-11-04 08:21:11 +00:00 
			
		
		
		
	* update github.com/alecthomas/chroma v0.8.0 -> v0.8.1 * github.com/blevesearch/bleve v1.0.10 -> v1.0.12 * editorconfig-core-go v2.1.1 -> v2.3.7 * github.com/gliderlabs/ssh v0.2.2 -> v0.3.1 * migrate editorconfig.ParseBytes to Parse * github.com/shurcooL/vfsgen to 0d455de96546 * github.com/go-git/go-git/v5 v5.1.0 -> v5.2.0 * github.com/google/uuid v1.1.1 -> v1.1.2 * github.com/huandu/xstrings v1.3.0 -> v1.3.2 * github.com/klauspost/compress v1.10.11 -> v1.11.1 * github.com/markbates/goth v1.61.2 -> v1.65.0 * github.com/mattn/go-sqlite3 v1.14.0 -> v1.14.4 * github.com/mholt/archiver v3.3.0 -> v3.3.2 * github.com/microcosm-cc/bluemonday 4f7140c49acb -> v1.0.4 * github.com/minio/minio-go v7.0.4 -> v7.0.5 * github.com/olivere/elastic v7.0.9 -> v7.0.20 * github.com/urfave/cli v1.20.0 -> v1.22.4 * github.com/prometheus/client_golang v1.1.0 -> v1.8.0 * github.com/xanzy/go-gitlab v0.37.0 -> v0.38.1 * mvdan.cc/xurls v2.1.0 -> v2.2.0 Co-authored-by: Lauris BH <lauris@nix.lv>
		
			
				
	
	
		
			592 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			592 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
package brotli
 | 
						|
 | 
						|
import "math"
 | 
						|
 | 
						|
/* Copyright 2010 Google Inc. All Rights Reserved.
 | 
						|
 | 
						|
   Distributed under MIT license.
 | 
						|
   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
 | 
						|
*/
 | 
						|
 | 
						|
/* Entropy encoding (Huffman) utilities. */
 | 
						|
 | 
						|
/* A node of a Huffman tree. */
 | 
						|
type huffmanTree struct {
 | 
						|
	total_count_          uint32
 | 
						|
	index_left_           int16
 | 
						|
	index_right_or_value_ int16
 | 
						|
}
 | 
						|
 | 
						|
func initHuffmanTree(self *huffmanTree, count uint32, left int16, right int16) {
 | 
						|
	self.total_count_ = count
 | 
						|
	self.index_left_ = left
 | 
						|
	self.index_right_or_value_ = right
 | 
						|
}
 | 
						|
 | 
						|
/* Input size optimized Shell sort. */
 | 
						|
type huffmanTreeComparator func(huffmanTree, huffmanTree) bool
 | 
						|
 | 
						|
var sortHuffmanTreeItems_gaps = []uint{132, 57, 23, 10, 4, 1}
 | 
						|
 | 
						|
func sortHuffmanTreeItems(items []huffmanTree, n uint, comparator huffmanTreeComparator) {
 | 
						|
	if n < 13 {
 | 
						|
		/* Insertion sort. */
 | 
						|
		var i uint
 | 
						|
		for i = 1; i < n; i++ {
 | 
						|
			var tmp huffmanTree = items[i]
 | 
						|
			var k uint = i
 | 
						|
			var j uint = i - 1
 | 
						|
			for comparator(tmp, items[j]) {
 | 
						|
				items[k] = items[j]
 | 
						|
				k = j
 | 
						|
				if j == 0 {
 | 
						|
					break
 | 
						|
				}
 | 
						|
				j--
 | 
						|
			}
 | 
						|
 | 
						|
			items[k] = tmp
 | 
						|
		}
 | 
						|
 | 
						|
		return
 | 
						|
	} else {
 | 
						|
		var g int
 | 
						|
		if n < 57 {
 | 
						|
			g = 2
 | 
						|
		} else {
 | 
						|
			g = 0
 | 
						|
		}
 | 
						|
		for ; g < 6; g++ {
 | 
						|
			var gap uint = sortHuffmanTreeItems_gaps[g]
 | 
						|
			var i uint
 | 
						|
			for i = gap; i < n; i++ {
 | 
						|
				var j uint = i
 | 
						|
				var tmp huffmanTree = items[i]
 | 
						|
				for ; j >= gap && comparator(tmp, items[j-gap]); j -= gap {
 | 
						|
					items[j] = items[j-gap]
 | 
						|
				}
 | 
						|
 | 
						|
				items[j] = tmp
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/* Returns 1 if assignment of depths succeeded, otherwise 0. */
 | 
						|
func setDepth(p0 int, pool []huffmanTree, depth []byte, max_depth int) bool {
 | 
						|
	var stack [16]int
 | 
						|
	var level int = 0
 | 
						|
	var p int = p0
 | 
						|
	assert(max_depth <= 15)
 | 
						|
	stack[0] = -1
 | 
						|
	for {
 | 
						|
		if pool[p].index_left_ >= 0 {
 | 
						|
			level++
 | 
						|
			if level > max_depth {
 | 
						|
				return false
 | 
						|
			}
 | 
						|
			stack[level] = int(pool[p].index_right_or_value_)
 | 
						|
			p = int(pool[p].index_left_)
 | 
						|
			continue
 | 
						|
		} else {
 | 
						|
			depth[pool[p].index_right_or_value_] = byte(level)
 | 
						|
		}
 | 
						|
 | 
						|
		for level >= 0 && stack[level] == -1 {
 | 
						|
			level--
 | 
						|
		}
 | 
						|
		if level < 0 {
 | 
						|
			return true
 | 
						|
		}
 | 
						|
		p = stack[level]
 | 
						|
		stack[level] = -1
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/* Sort the root nodes, least popular first. */
 | 
						|
func sortHuffmanTree(v0 huffmanTree, v1 huffmanTree) bool {
 | 
						|
	if v0.total_count_ != v1.total_count_ {
 | 
						|
		return v0.total_count_ < v1.total_count_
 | 
						|
	}
 | 
						|
 | 
						|
	return v0.index_right_or_value_ > v1.index_right_or_value_
 | 
						|
}
 | 
						|
 | 
						|
/* This function will create a Huffman tree.
 | 
						|
 | 
						|
   The catch here is that the tree cannot be arbitrarily deep.
 | 
						|
   Brotli specifies a maximum depth of 15 bits for "code trees"
 | 
						|
   and 7 bits for "code length code trees."
 | 
						|
 | 
						|
   count_limit is the value that is to be faked as the minimum value
 | 
						|
   and this minimum value is raised until the tree matches the
 | 
						|
   maximum length requirement.
 | 
						|
 | 
						|
   This algorithm is not of excellent performance for very long data blocks,
 | 
						|
   especially when population counts are longer than 2**tree_limit, but
 | 
						|
   we are not planning to use this with extremely long blocks.
 | 
						|
 | 
						|
   See http://en.wikipedia.org/wiki/Huffman_coding */
 | 
						|
func createHuffmanTree(data []uint32, length uint, tree_limit int, tree []huffmanTree, depth []byte) {
 | 
						|
	var count_limit uint32
 | 
						|
	var sentinel huffmanTree
 | 
						|
	initHuffmanTree(&sentinel, math.MaxUint32, -1, -1)
 | 
						|
 | 
						|
	/* For block sizes below 64 kB, we never need to do a second iteration
 | 
						|
	   of this loop. Probably all of our block sizes will be smaller than
 | 
						|
	   that, so this loop is mostly of academic interest. If we actually
 | 
						|
	   would need this, we would be better off with the Katajainen algorithm. */
 | 
						|
	for count_limit = 1; ; count_limit *= 2 {
 | 
						|
		var n uint = 0
 | 
						|
		var i uint
 | 
						|
		var j uint
 | 
						|
		var k uint
 | 
						|
		for i = length; i != 0; {
 | 
						|
			i--
 | 
						|
			if data[i] != 0 {
 | 
						|
				var count uint32 = brotli_max_uint32_t(data[i], count_limit)
 | 
						|
				initHuffmanTree(&tree[n], count, -1, int16(i))
 | 
						|
				n++
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if n == 1 {
 | 
						|
			depth[tree[0].index_right_or_value_] = 1 /* Only one element. */
 | 
						|
			break
 | 
						|
		}
 | 
						|
 | 
						|
		sortHuffmanTreeItems(tree, n, huffmanTreeComparator(sortHuffmanTree))
 | 
						|
 | 
						|
		/* The nodes are:
 | 
						|
		   [0, n): the sorted leaf nodes that we start with.
 | 
						|
		   [n]: we add a sentinel here.
 | 
						|
		   [n + 1, 2n): new parent nodes are added here, starting from
 | 
						|
		                (n+1). These are naturally in ascending order.
 | 
						|
		   [2n]: we add a sentinel at the end as well.
 | 
						|
		   There will be (2n+1) elements at the end. */
 | 
						|
		tree[n] = sentinel
 | 
						|
 | 
						|
		tree[n+1] = sentinel
 | 
						|
 | 
						|
		i = 0     /* Points to the next leaf node. */
 | 
						|
		j = n + 1 /* Points to the next non-leaf node. */
 | 
						|
		for k = n - 1; k != 0; k-- {
 | 
						|
			var left uint
 | 
						|
			var right uint
 | 
						|
			if tree[i].total_count_ <= tree[j].total_count_ {
 | 
						|
				left = i
 | 
						|
				i++
 | 
						|
			} else {
 | 
						|
				left = j
 | 
						|
				j++
 | 
						|
			}
 | 
						|
 | 
						|
			if tree[i].total_count_ <= tree[j].total_count_ {
 | 
						|
				right = i
 | 
						|
				i++
 | 
						|
			} else {
 | 
						|
				right = j
 | 
						|
				j++
 | 
						|
			}
 | 
						|
			{
 | 
						|
				/* The sentinel node becomes the parent node. */
 | 
						|
				var j_end uint = 2*n - k
 | 
						|
				tree[j_end].total_count_ = tree[left].total_count_ + tree[right].total_count_
 | 
						|
				tree[j_end].index_left_ = int16(left)
 | 
						|
				tree[j_end].index_right_or_value_ = int16(right)
 | 
						|
 | 
						|
				/* Add back the last sentinel node. */
 | 
						|
				tree[j_end+1] = sentinel
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if setDepth(int(2*n-1), tree[0:], depth, tree_limit) {
 | 
						|
			/* We need to pack the Huffman tree in tree_limit bits. If this was not
 | 
						|
			   successful, add fake entities to the lowest values and retry. */
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func reverse(v []byte, start uint, end uint) {
 | 
						|
	end--
 | 
						|
	for start < end {
 | 
						|
		var tmp byte = v[start]
 | 
						|
		v[start] = v[end]
 | 
						|
		v[end] = tmp
 | 
						|
		start++
 | 
						|
		end--
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func writeHuffmanTreeRepetitions(previous_value byte, value byte, repetitions uint, tree_size *uint, tree []byte, extra_bits_data []byte) {
 | 
						|
	assert(repetitions > 0)
 | 
						|
	if previous_value != value {
 | 
						|
		tree[*tree_size] = value
 | 
						|
		extra_bits_data[*tree_size] = 0
 | 
						|
		(*tree_size)++
 | 
						|
		repetitions--
 | 
						|
	}
 | 
						|
 | 
						|
	if repetitions == 7 {
 | 
						|
		tree[*tree_size] = value
 | 
						|
		extra_bits_data[*tree_size] = 0
 | 
						|
		(*tree_size)++
 | 
						|
		repetitions--
 | 
						|
	}
 | 
						|
 | 
						|
	if repetitions < 3 {
 | 
						|
		var i uint
 | 
						|
		for i = 0; i < repetitions; i++ {
 | 
						|
			tree[*tree_size] = value
 | 
						|
			extra_bits_data[*tree_size] = 0
 | 
						|
			(*tree_size)++
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		var start uint = *tree_size
 | 
						|
		repetitions -= 3
 | 
						|
		for {
 | 
						|
			tree[*tree_size] = repeatPreviousCodeLength
 | 
						|
			extra_bits_data[*tree_size] = byte(repetitions & 0x3)
 | 
						|
			(*tree_size)++
 | 
						|
			repetitions >>= 2
 | 
						|
			if repetitions == 0 {
 | 
						|
				break
 | 
						|
			}
 | 
						|
 | 
						|
			repetitions--
 | 
						|
		}
 | 
						|
 | 
						|
		reverse(tree, start, *tree_size)
 | 
						|
		reverse(extra_bits_data, start, *tree_size)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func writeHuffmanTreeRepetitionsZeros(repetitions uint, tree_size *uint, tree []byte, extra_bits_data []byte) {
 | 
						|
	if repetitions == 11 {
 | 
						|
		tree[*tree_size] = 0
 | 
						|
		extra_bits_data[*tree_size] = 0
 | 
						|
		(*tree_size)++
 | 
						|
		repetitions--
 | 
						|
	}
 | 
						|
 | 
						|
	if repetitions < 3 {
 | 
						|
		var i uint
 | 
						|
		for i = 0; i < repetitions; i++ {
 | 
						|
			tree[*tree_size] = 0
 | 
						|
			extra_bits_data[*tree_size] = 0
 | 
						|
			(*tree_size)++
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		var start uint = *tree_size
 | 
						|
		repetitions -= 3
 | 
						|
		for {
 | 
						|
			tree[*tree_size] = repeatZeroCodeLength
 | 
						|
			extra_bits_data[*tree_size] = byte(repetitions & 0x7)
 | 
						|
			(*tree_size)++
 | 
						|
			repetitions >>= 3
 | 
						|
			if repetitions == 0 {
 | 
						|
				break
 | 
						|
			}
 | 
						|
 | 
						|
			repetitions--
 | 
						|
		}
 | 
						|
 | 
						|
		reverse(tree, start, *tree_size)
 | 
						|
		reverse(extra_bits_data, start, *tree_size)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/* Change the population counts in a way that the consequent
 | 
						|
   Huffman tree compression, especially its RLE-part will be more
 | 
						|
   likely to compress this data more efficiently.
 | 
						|
 | 
						|
   length contains the size of the histogram.
 | 
						|
   counts contains the population counts.
 | 
						|
   good_for_rle is a buffer of at least length size */
 | 
						|
func optimizeHuffmanCountsForRLE(length uint, counts []uint32, good_for_rle []byte) {
 | 
						|
	var nonzero_count uint = 0
 | 
						|
	var stride uint
 | 
						|
	var limit uint
 | 
						|
	var sum uint
 | 
						|
	var streak_limit uint = 1240
 | 
						|
	var i uint
 | 
						|
	/* Let's make the Huffman code more compatible with RLE encoding. */
 | 
						|
	for i = 0; i < length; i++ {
 | 
						|
		if counts[i] != 0 {
 | 
						|
			nonzero_count++
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if nonzero_count < 16 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	for length != 0 && counts[length-1] == 0 {
 | 
						|
		length--
 | 
						|
	}
 | 
						|
 | 
						|
	if length == 0 {
 | 
						|
		return /* All zeros. */
 | 
						|
	}
 | 
						|
 | 
						|
	/* Now counts[0..length - 1] does not have trailing zeros. */
 | 
						|
	{
 | 
						|
		var nonzeros uint = 0
 | 
						|
		var smallest_nonzero uint32 = 1 << 30
 | 
						|
		for i = 0; i < length; i++ {
 | 
						|
			if counts[i] != 0 {
 | 
						|
				nonzeros++
 | 
						|
				if smallest_nonzero > counts[i] {
 | 
						|
					smallest_nonzero = counts[i]
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if nonzeros < 5 {
 | 
						|
			/* Small histogram will model it well. */
 | 
						|
			return
 | 
						|
		}
 | 
						|
 | 
						|
		if smallest_nonzero < 4 {
 | 
						|
			var zeros uint = length - nonzeros
 | 
						|
			if zeros < 6 {
 | 
						|
				for i = 1; i < length-1; i++ {
 | 
						|
					if counts[i-1] != 0 && counts[i] == 0 && counts[i+1] != 0 {
 | 
						|
						counts[i] = 1
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if nonzeros < 28 {
 | 
						|
			return
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/* 2) Let's mark all population counts that already can be encoded
 | 
						|
	   with an RLE code. */
 | 
						|
	for i := 0; i < int(length); i++ {
 | 
						|
		good_for_rle[i] = 0
 | 
						|
	}
 | 
						|
	{
 | 
						|
		var symbol uint32 = counts[0]
 | 
						|
		/* Let's not spoil any of the existing good RLE codes.
 | 
						|
		   Mark any seq of 0's that is longer as 5 as a good_for_rle.
 | 
						|
		   Mark any seq of non-0's that is longer as 7 as a good_for_rle. */
 | 
						|
 | 
						|
		var step uint = 0
 | 
						|
		for i = 0; i <= length; i++ {
 | 
						|
			if i == length || counts[i] != symbol {
 | 
						|
				if (symbol == 0 && step >= 5) || (symbol != 0 && step >= 7) {
 | 
						|
					var k uint
 | 
						|
					for k = 0; k < step; k++ {
 | 
						|
						good_for_rle[i-k-1] = 1
 | 
						|
					}
 | 
						|
				}
 | 
						|
 | 
						|
				step = 1
 | 
						|
				if i != length {
 | 
						|
					symbol = counts[i]
 | 
						|
				}
 | 
						|
			} else {
 | 
						|
				step++
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/* 3) Let's replace those population counts that lead to more RLE codes.
 | 
						|
	   Math here is in 24.8 fixed point representation. */
 | 
						|
	stride = 0
 | 
						|
 | 
						|
	limit = uint(256*(counts[0]+counts[1]+counts[2])/3 + 420)
 | 
						|
	sum = 0
 | 
						|
	for i = 0; i <= length; i++ {
 | 
						|
		if i == length || good_for_rle[i] != 0 || (i != 0 && good_for_rle[i-1] != 0) || (256*counts[i]-uint32(limit)+uint32(streak_limit)) >= uint32(2*streak_limit) {
 | 
						|
			if stride >= 4 || (stride >= 3 && sum == 0) {
 | 
						|
				var k uint
 | 
						|
				var count uint = (sum + stride/2) / stride
 | 
						|
				/* The stride must end, collapse what we have, if we have enough (4). */
 | 
						|
				if count == 0 {
 | 
						|
					count = 1
 | 
						|
				}
 | 
						|
 | 
						|
				if sum == 0 {
 | 
						|
					/* Don't make an all zeros stride to be upgraded to ones. */
 | 
						|
					count = 0
 | 
						|
				}
 | 
						|
 | 
						|
				for k = 0; k < stride; k++ {
 | 
						|
					/* We don't want to change value at counts[i],
 | 
						|
					   that is already belonging to the next stride. Thus - 1. */
 | 
						|
					counts[i-k-1] = uint32(count)
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			stride = 0
 | 
						|
			sum = 0
 | 
						|
			if i < length-2 {
 | 
						|
				/* All interesting strides have a count of at least 4, */
 | 
						|
				/* at least when non-zeros. */
 | 
						|
				limit = uint(256*(counts[i]+counts[i+1]+counts[i+2])/3 + 420)
 | 
						|
			} else if i < length {
 | 
						|
				limit = uint(256 * counts[i])
 | 
						|
			} else {
 | 
						|
				limit = 0
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		stride++
 | 
						|
		if i != length {
 | 
						|
			sum += uint(counts[i])
 | 
						|
			if stride >= 4 {
 | 
						|
				limit = (256*sum + stride/2) / stride
 | 
						|
			}
 | 
						|
 | 
						|
			if stride == 4 {
 | 
						|
				limit += 120
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func decideOverRLEUse(depth []byte, length uint, use_rle_for_non_zero *bool, use_rle_for_zero *bool) {
 | 
						|
	var total_reps_zero uint = 0
 | 
						|
	var total_reps_non_zero uint = 0
 | 
						|
	var count_reps_zero uint = 1
 | 
						|
	var count_reps_non_zero uint = 1
 | 
						|
	var i uint
 | 
						|
	for i = 0; i < length; {
 | 
						|
		var value byte = depth[i]
 | 
						|
		var reps uint = 1
 | 
						|
		var k uint
 | 
						|
		for k = i + 1; k < length && depth[k] == value; k++ {
 | 
						|
			reps++
 | 
						|
		}
 | 
						|
 | 
						|
		if reps >= 3 && value == 0 {
 | 
						|
			total_reps_zero += reps
 | 
						|
			count_reps_zero++
 | 
						|
		}
 | 
						|
 | 
						|
		if reps >= 4 && value != 0 {
 | 
						|
			total_reps_non_zero += reps
 | 
						|
			count_reps_non_zero++
 | 
						|
		}
 | 
						|
 | 
						|
		i += reps
 | 
						|
	}
 | 
						|
 | 
						|
	*use_rle_for_non_zero = total_reps_non_zero > count_reps_non_zero*2
 | 
						|
	*use_rle_for_zero = total_reps_zero > count_reps_zero*2
 | 
						|
}
 | 
						|
 | 
						|
/* Write a Huffman tree from bit depths into the bit-stream representation
 | 
						|
   of a Huffman tree. The generated Huffman tree is to be compressed once
 | 
						|
   more using a Huffman tree */
 | 
						|
func writeHuffmanTree(depth []byte, length uint, tree_size *uint, tree []byte, extra_bits_data []byte) {
 | 
						|
	var previous_value byte = initialRepeatedCodeLength
 | 
						|
	var i uint
 | 
						|
	var use_rle_for_non_zero bool = false
 | 
						|
	var use_rle_for_zero bool = false
 | 
						|
	var new_length uint = length
 | 
						|
	/* Throw away trailing zeros. */
 | 
						|
	for i = 0; i < length; i++ {
 | 
						|
		if depth[length-i-1] == 0 {
 | 
						|
			new_length--
 | 
						|
		} else {
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/* First gather statistics on if it is a good idea to do RLE. */
 | 
						|
	if length > 50 {
 | 
						|
		/* Find RLE coding for longer codes.
 | 
						|
		   Shorter codes seem not to benefit from RLE. */
 | 
						|
		decideOverRLEUse(depth, new_length, &use_rle_for_non_zero, &use_rle_for_zero)
 | 
						|
	}
 | 
						|
 | 
						|
	/* Actual RLE coding. */
 | 
						|
	for i = 0; i < new_length; {
 | 
						|
		var value byte = depth[i]
 | 
						|
		var reps uint = 1
 | 
						|
		if (value != 0 && use_rle_for_non_zero) || (value == 0 && use_rle_for_zero) {
 | 
						|
			var k uint
 | 
						|
			for k = i + 1; k < new_length && depth[k] == value; k++ {
 | 
						|
				reps++
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if value == 0 {
 | 
						|
			writeHuffmanTreeRepetitionsZeros(reps, tree_size, tree, extra_bits_data)
 | 
						|
		} else {
 | 
						|
			writeHuffmanTreeRepetitions(previous_value, value, reps, tree_size, tree, extra_bits_data)
 | 
						|
			previous_value = value
 | 
						|
		}
 | 
						|
 | 
						|
		i += reps
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
var reverseBits_kLut = [16]uint{
 | 
						|
	0x00,
 | 
						|
	0x08,
 | 
						|
	0x04,
 | 
						|
	0x0C,
 | 
						|
	0x02,
 | 
						|
	0x0A,
 | 
						|
	0x06,
 | 
						|
	0x0E,
 | 
						|
	0x01,
 | 
						|
	0x09,
 | 
						|
	0x05,
 | 
						|
	0x0D,
 | 
						|
	0x03,
 | 
						|
	0x0B,
 | 
						|
	0x07,
 | 
						|
	0x0F,
 | 
						|
}
 | 
						|
 | 
						|
func reverseBits(num_bits uint, bits uint16) uint16 {
 | 
						|
	var retval uint = reverseBits_kLut[bits&0x0F]
 | 
						|
	var i uint
 | 
						|
	for i = 4; i < num_bits; i += 4 {
 | 
						|
		retval <<= 4
 | 
						|
		bits = uint16(bits >> 4)
 | 
						|
		retval |= reverseBits_kLut[bits&0x0F]
 | 
						|
	}
 | 
						|
 | 
						|
	retval >>= ((0 - num_bits) & 0x03)
 | 
						|
	return uint16(retval)
 | 
						|
}
 | 
						|
 | 
						|
/* 0..15 are values for bits */
 | 
						|
const maxHuffmanBits = 16
 | 
						|
 | 
						|
/* Get the actual bit values for a tree of bit depths. */
 | 
						|
func convertBitDepthsToSymbols(depth []byte, len uint, bits []uint16) {
 | 
						|
	var bl_count = [maxHuffmanBits]uint16{0}
 | 
						|
	var next_code [maxHuffmanBits]uint16
 | 
						|
	var i uint
 | 
						|
	/* In Brotli, all bit depths are [1..15]
 | 
						|
	   0 bit depth means that the symbol does not exist. */
 | 
						|
 | 
						|
	var code int = 0
 | 
						|
	for i = 0; i < len; i++ {
 | 
						|
		bl_count[depth[i]]++
 | 
						|
	}
 | 
						|
 | 
						|
	bl_count[0] = 0
 | 
						|
	next_code[0] = 0
 | 
						|
	for i = 1; i < maxHuffmanBits; i++ {
 | 
						|
		code = (code + int(bl_count[i-1])) << 1
 | 
						|
		next_code[i] = uint16(code)
 | 
						|
	}
 | 
						|
 | 
						|
	for i = 0; i < len; i++ {
 | 
						|
		if depth[i] != 0 {
 | 
						|
			bits[i] = reverseBits(uint(depth[i]), next_code[depth[i]])
 | 
						|
			next_code[depth[i]]++
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |