mirror of
https://github.com/tsolomko/SWCompression.git
synced 2026-06-23 14:56:41 +00:00
More elegant solution for zero code lengths problem
This commit is contained in:
+3
-1
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user