More elegant solution for zero code lengths problem

This commit is contained in:
Timofey Solomko
2017-09-03 19:59:46 +03:00
parent 69fa9a2646
commit f96f446827
4 changed files with 12 additions and 7 deletions
+3 -1
View File
@@ -142,7 +142,9 @@ public class BZip2: DecompressionAlgorithm {
while bitReader.bit() > 0 {
length -= (Int(bitReader.bit() * 2) - 1)
}
lengths.append(HuffmanLength(symbol: i, codeLength: length))
if length > 0 {
lengths.append(HuffmanLength(symbol: i, codeLength: length))
}
}
let table = DecodingHuffmanTree(lengths: lengths, bitReader)
tables.append(table)
+3 -2
View File
@@ -12,12 +12,12 @@ class DecodingHuffmanTree {
private var tree: [Int]
private let leafCount: Int
/// `lengths` don't have to be properly sorted.
/// `lengths` don't have to be properly sorted, but there must not be any 0 code lengths.
init(lengths: [HuffmanLength], _ bitReader: BitReader) {
self.bitReader = bitReader
// Sort `lengths` array to calculate canonical Huffman code.
let sortedLengths = lengths.filter { $0.codeLength > 0 }.sorted { (left: HuffmanLength, right: HuffmanLength) -> Bool in
let sortedLengths = lengths.sorted { (left: HuffmanLength, right: HuffmanLength) -> Bool in
if left.codeLength == right.codeLength {
return left.symbol < right.symbol
} else {
@@ -47,6 +47,7 @@ class DecodingHuffmanTree {
var loopBits = -1
var symbol = -1
for length in sortedLengths {
precondition(length.codeLength > 0, "Code length must not be 0 during HuffmanTree construction.")
symbol += 1
// We sometimes need to make symbol to have length.bits bit length.
let bits = length.codeLength
+3 -2
View File
@@ -11,12 +11,12 @@ class EncodingHuffmanTree {
private var codingIndices: [[Int]]
/// `lengths` don't have to be properly sorted.
/// `lengths` don't have to be properly sorted, but there must not be any 0 code lengths.
init(lengths: [HuffmanLength], _ bitWriter: BitWriter) {
self.bitWriter = bitWriter
// Sort `lengths` array to calculate canonical Huffman code.
let sortedLengths = lengths.filter { $0.codeLength > 0 }.sorted { (left: HuffmanLength, right: HuffmanLength) -> Bool in
let sortedLengths = lengths.sorted { (left: HuffmanLength, right: HuffmanLength) -> Bool in
if left.codeLength == right.codeLength {
return left.symbol < right.symbol
} else {
@@ -44,6 +44,7 @@ class EncodingHuffmanTree {
var loopBits = -1
var symbol = -1
for length in sortedLengths {
precondition(length.codeLength > 0, "Code length must not be 0 during HuffmanTree construction.")
symbol += 1
// We sometimes need to make symbol to have length.bits bit length.
let bits = length.codeLength
+3 -2
View File
@@ -29,10 +29,11 @@ struct HuffmanLength {
return lengths
}
/// - Note: Skips zero codeLengths.
static func lengths(from orderedCodeLengths: [Int]) -> [HuffmanLength] {
var lengths = [HuffmanLength]()
for i in 0..<orderedCodeLengths.count {
lengths.append(HuffmanLength(symbol: i, codeLength: orderedCodeLengths[i]))
for (i, codeLength) in orderedCodeLengths.enumerated() where codeLength > 0 {
lengths.append(HuffmanLength(symbol: i, codeLength: codeLength))
}
return lengths
}