Example #1
0
func TestGenerateTreesLowest(t *testing.T) {
	_, reduced := symbols.Get([]byte("banana"))
	data := []uint16{'\x03', '\x00', '\x03', '\x00', '\x01', '\x04'}
	freqs := rle2.GetFrequencies(reduced, data)

	trees, selections := GenerateTrees(freqs, data)
	if len(trees) < 2 {
		t.Error("Not enough huffman trees generated")
	}
	if len(trees) > 6 {
		t.Error("Too many huffman trees generated")
	}

	if len(selections) != 1 {
		t.Error("The wrong number of huffman tree selections was returned")
	}
}
Example #2
0
func TestTreeCodeLength(t *testing.T) {
	_, reduced := symbols.Get([]byte("banana"))
	data := []uint16{'\x03', '\x00', '\x03', '\x00', '\x01', '\x04'}
	freqs := rle2.GetFrequencies(reduced, data)

	lowestlen := 0
	tree := NewTree(freqs)
	for i, code := range tree.Codes {
		if i == 0 || code.Len < lowestlen {
			lowestlen = code.Len
		}
	}

	if lowestlen != tree.Codes['\x03'].Len {
		t.Error("The lowest code-length isn't the most used symbol")
	}
}
Example #3
0
func TestGenerateTreesMultipleSelections(t *testing.T) {
	_, reduced := symbols.Get([]byte("banana"))
	data := []uint16{'\x03', '\x00', '\x03', '\x00', '\x01', '\x04'}
	base := data
	for len(data) <= 200 {
		data = append(data, base...)
	}
	freqs := rle2.GetFrequencies(reduced, data)

	trees, selections := GenerateTrees(freqs, data)
	if len(trees) < 2 {
		t.Error("Not enough huffman trees generated")
	}
	if len(trees) > 6 {
		t.Error("Too many huffman trees generated")
	}

	if len(selections) != 5 {
		t.Error("The wrong number of huffman tree selections was returned")
	}
}
Example #4
0
// WriteBlock compresses the content buffered and writes
// a block to the bit writer given.
func (b *block) WriteBlock(bw *bits.Writer) error {
	rleData := b.runs.Encode()
	syms, reducedSyms := symbols.Get(rleData)

	// BWT step.
	bwtData := make([]byte, len(rleData))
	bwtidx := bwt.Transform(bwtData, rleData)

	// MTF step.
	mtfData := bwtData
	mtf.Transform(reducedSyms, mtfData, bwtData)

	// RLE2 step.
	rle2Data := rle2.Encode(reducedSyms, mtfData)
	freqs := rle2.GetFrequencies(reducedSyms, rle2Data)

	// Setup the huffman trees required to encode rle2Data.
	trees, selections := huffman.GenerateTrees(freqs, rle2Data)

	// Get the MTF encoded huffman tree selections.
	treeSelectionSymbols := make(symbols.ReducedSet, len(trees))
	for i := range trees {
		treeSelectionSymbols[i] = byte(i)
	}
	treeSelectionBytes := make([]byte, len(selections))
	for i, selection := range selections {
		treeSelectionBytes[i] = byte(selection)
	}
	mtf.Transform(treeSelectionSymbols, treeSelectionBytes, treeSelectionBytes)

	// Write the block header.
	bw.WriteBits(48, blockMagic)
	bw.WriteBits(32, uint64(b.crc))
	bw.WriteBits(1, 0)

	// Write the contents that build the decoding steps.
	bw.WriteBits(24, uint64(bwtidx))
	b.writeSymbolBitmaps(bw, syms)
	bw.WriteBits(3, uint64(len(trees)))
	bw.WriteBits(15, uint64(len(selections)))
	b.writeTreeSelections(bw, treeSelectionBytes)
	b.writeTreeCodes(bw, trees)

	// Write the encoded contents, using the huffman trees generated
	// switching them out every 50 symbols.
	encoded := 0
	idx := 0
	tree := trees[selections[idx]]
	for _, b := range rle2Data {
		if encoded == huffman.TreeSelectionLimit {
			encoded = 0
			idx++
			tree = trees[selections[idx]]
		}
		code := tree.Codes[b]

		bw.WriteBits(uint(code.Len), code.Bits)
		encoded++
	}

	return bw.Err()
}